虚拟函数导致moc生成的.o文件中出现未定义的引用错误



为什么以下代码在编译时给我一个未定义的引用错误?

#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的引用(charconst*('

如果将virtual void input_port_impk( const char *data );更改为void input_port_impk( const char *data );virtual void input_port_impk( const char *data ) = 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(,这将是允许的,但我将与访问不同类的受保护成员函数的条件相冲突(该类不是基类,也不会编译(。更糟糕的是,如果我知道派生对象的子类类型,即使转换到它的公共基,我仍然无法访问它。

为什么要强制执行这种行为?我认为这可能是允许多重继承等的副作用,但我想不出它会是什么。这很烦人,因为现在我必须为一些现在和应该只由基类或派生类使用的东西创建一个公共接口,这违背了继承和访问修饰符的观点。

链接--http://en.cppreference.com/w/cpp/language/access

最新更新