为什么下面的代码在编译时给我一个未定义的引用错误?
#include <QObject>
class QT_PORT_WRAPPER_C : public QObject
{
Q_OBJECT
public:
//constructor
QT_PORT_WRAPPER_C(){};
protected:
virtual void input_port_impk( const char *data ); //causes error
};
错误消息是:
/home/abc/work/build-exp-Desktop_Qt_5_10_0_GCC_64bit-Debug/moc_receiver.o:-1: 错误:未定义对`QT_PORT_WRAPPER_C :: input_port_impk的引用(字符 const *)'
如果我将virtual void input_port_impk( const char *data );
更改为void input_port_impk( const char *data );
或virtual void input_port_impk( const char *data ) = 0;
,则错误消失了。为什么?
答案 0 :(得分:0)
不允许通过派生类内部的基类类型的指针访问基类的虚拟受保护功能
#include <iostream>
class Base {
public:
void go(){this->doSomething();}
protected:
virtual void doSomething(){std::cout << "base";}
};
class DerivedA : public Base {
protected:
void doSomething() override {std::cout << "a";}
};
class DerivedB : public Base {
public:
Base * basePtr;
DerivedB()
:basePtr(new DerivedA())
{}
protected:
void doSomething() override {basePtr->doSomething();} // wont compile
};
int main(int , char *[])
{
DerivedB b;
b.go();
}
DerivedB子类中的doSomething()无法编译,但是我不明白为什么存在此行为!我正在尝试访问我的基类的虚拟受保护成员函数,我本以为会允许这样做的。
在受保护成员访问部分中,
“ Base的类的受保护成员只能(1)由Base的成员和朋友访问2)派生自Base的任何类的成员和朋友(直到C ++ 17),但仅当在从Base(包括此对象)派生的类型的对象”
根据第2点,如果我强制转换为子类(DerivedA),则允许这样做,但与我要访问其他类的受保护成员函数(不是基本类,也不会编译)。更糟糕的是,如果我知道派生对象的子类类型,即使将其强制转换为它的公共基础,我仍然无法访问它。
为什么要强制执行此行为?我认为这可能是允许多重继承等的副作用,但我想不出到底是什么。这很烦人,因为现在我必须为必须是基类或派生类使用的东西建立一个公共接口,这违背了继承和访问修饰符的观点。