Виртуальная функция, вызывающая неопределенную ошибку ссылки в сгенерированных moc файлах .o - PullRequest
0 голосов
/ 28 ноября 2018

Почему следующий код дает мне неопределенную ошибку ссылки при компиляции?

#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 (char 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;, ошибка исчезнет.Почему?

1 Ответ

0 голосов
/ 28 ноября 2018

доступ к виртуальным защищенным функциям базового класса не разрешен через указатель типа базового класса внутри производного класса

#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();
}

doSomething () в подклассе DerivedB не будет компилироваться, но я не понимаюпочему такое поведение существует!Я пытаюсь получить доступ к функции виртуального защищенного члена моего базового класса, которая, как я думал, будет разрешена.

В разделе о доступе к защищенному члену написано

"Защищенный членкласса Base могут быть доступны только 1) членам и друзьям Base 2) членам и друзьям (до C ++ 17) любого класса, производного от Base, но только при работе с объектом типа, который являетсяпроизводный от Base (включая это) "

Согласно пункту 2, если я приведу к подклассу (DerivedA), это будет разрешено, но тогда я буду в конфликте с условием доступа к защищенномуфункция-член другого класса (который не является базовым классом и также не будет компилироваться).Хуже того, если бы я знал тип подкласса производного объекта, я все равно не смог бы получить к нему доступ, даже если приведу к его общей базе.

Почему это поведение применяется?Я предполагаю, что это, вероятно, будет побочным эффектом разрешения множественного наследования и т. Д., Но я не могу думать точно, что это будет.Это раздражает, потому что теперь я должен сделать открытый интерфейс для чего-то, что должно и должно использоваться только базовыми или производными классами, что противоречит точке наследования и модификаторам доступа.

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

...