当存在另一个具有另一个签名的成员时,调用纯虚成员的正确方法是什么?
What is the correct way to call the pure virtual member when another member exists with another signature?
我有一个纯虚接口类和一个派生类,如下所示
class IInterface
{
public:
virtual void func() = 0;
};
class MyClass : public IInterface
{
public:
void func(int i) { func(); }
};
编译器报错func(int i)
中对func()
的调用没有接受0个参数。什么是指定调用纯虚成员的正确方法?
我想到的两个解决方案是
void func(int i) { static_cast<IInterface*>(this)->func(); }
和
void func(int i) { IInterface::func(); }
这两个都可行吗?有没有更好的办法?
使用using-declaration:
将基类声明引入派生类作用域class MyClass : public IInterface
{
public:
using IInterface::func;
void func(int i) { func(); }
};
或者,将this
转换为指向基的指针也可以工作(即,您的第一个选项):
void func(int i) { static_cast<IInterface*>(this)->func(); }
IInterface::func();
不能工作,因为显式限定禁用虚拟调度。
如果您想避免在基类中隐藏名称,您可以使用using
语句:
class MyClass : public IInterface
{
public:
using IInterface::func; // prevents `func()` from being hidden by `func(int)`
void func(int i) { func(); }
};
这在Scott Meyers的"Effective c++, Third Edition"的第33条:"避免隐藏继承的名称"中有描述。
代码void func(int i) { func(); }
不起作用,因为当您在MyClass
的范围内声明func
时,该名称隐藏了基类中称为func
的任何其他名称。
如果您希望IInterface
的func()
在MyClass
作用域中普遍可用,最简单的解决方案是:
using IInterface::func;
可以放在MyClass的类定义中(并且会尊重你把它放在下面的访问说明符);或者你只能把它放在func(int i)
里面。在此之后,从MyClass
的作用域调用func
将在func()
和func(int)
之间进行过载解析。
static_cast<IInterface*>(this)->func();
也可以工作:它将为当前正在处理的对象调用func()
的最终重写。
IInterface::func()
版本不做虚调度;它实际上调用了特定的函数IInterface::func
。如果你没有定义这样一个函数,那么你将导致未定义的行为;这可能会显示为链接器错误,或者试图调用纯虚函数的运行时错误。
NB。如果你不知道,纯虚函数也可以定义一个函数体,但这很少在析构函数之外完成。
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何从另一个文件继承私有成员变量和公共函数
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 在作为静态成员包含在另一个类中的类的构造函数中使用 cout
- 为什么将一个结构的引用设置为等于另一个结构只会更改一个数据成员?
- 没有公共构造函数作为另一个类模板成员的类模板
- 将另一个类的对象传递到当前类C++的构造函数中(不是成员初始化)
- 将类成员函数作为线程调用到另一个类成员函数时发出警告消息
- 如何使用另一个类中的公共成员函数作为参数调用线程
- 是否可以使用智能指针成员设置具有另一个结构的结构?
- 使用指向成员函数的指针在另一个类中调用类构造函数
- 访问 std:vector 的类成员 std:vector 在一个类中与另一个 std:vector
- 无法将指向类的成员函数的函数指针作为参数传递给同一类的另一个成员函数
- 复制赋值函数如何访问另一个对象的私有成员(Stroustroup 原则和实践书)?
- 如何从另一个嵌套类中调用某个封闭类的嵌套类的函数指针成员的值?
- 在C++中,是否可以"overload"作为另一个类成员的对象?
- C++ - 非静态 void* 成员,指向具有相同地址但不同值的不同对象的另一个非静态成员
- 如何检查一个模板是否是另一个模板的类成员
- 如何在另一个类中使用类成员的正确方法?