Использование абстрактного класса в C ++ - PullRequest
16 голосов
/ 16 марта 2009

Я пытаюсь использовать абстрактный класс при передаче расширенного объекта в качестве параметра функции, но мои попытки до сих пор приводили к некоторым ошибкам компилятора.

У меня есть несколько подсказок о том, в чем заключается проблема, мне явно не разрешено создавать экземпляр абстрактного класса, и я считаю, что часть кода в MyClass пытается это сделать, хотя это и не является моим намерением. Некоторые исследования предлагают, чтобы я достиг ссылки на объект как указатель, чтобы достичь того, чего я хочу, но мои попытки пока не увенчались успехом, и я даже не уверен, что это ответ (отсюда и мой вопрос здесь).

Я сообщу, что теперь я больше знаком с Java, чем с C ++, и уверен, что часть моей проблемы связана с этим.

Вот пример того, что я пытаюсь сделать в своей программе:

class A {
    public:
        virtual void action() = 0;
};

class B : public A {
    public:
        B() {}

        void action() {
            // Do stuff
        }
};

class MyClass {

    public:

        void setInstance(A newInstance) {
            instance = newInstance;
        }

        void doSomething() {
            instance.action();
        }

    private:

        A instance;
};

int main(int argc, char** argv) {
    MyClass c;
    B myInstance;
    c.setInstance(myInstance);
    c.doSomething();
    return 0;
}

Этот пример выдает ту же ошибку компилятора, которую я получаю в своей программе:

sean@SEAN-PC:~/Desktop$ gcc -o test test.cpp
test.cpp:20: error: cannot declare parameter ‘newInstance’ to be of abstract type ‘A’
test.cpp:2: note:   because the following virtual functions are pure within ‘A’:
test.cpp:4: note:   virtual void A::action()
test.cpp:30: error: cannot declare field ‘MyClass::instance’ to be of abstract type ‘A’
test.cpp:2: note:   since type ‘A’ has pure virtual functions
test.cpp: In function ‘int main(int, char**)’:
test.cpp:36: error: cannot allocate an object of abstract type ‘A’
test.cpp:2: note:   since type ‘A’ has pure virtual functions

Обновление

Спасибо всем за отзыв.

С тех пор я изменил "MyClass :: instance, чтобы он содержал указатель типа A, но теперь я получаю несколько странных ошибок, связанных с виртуальной таблицей:

sean@SEAN-PC:~/Desktop$ gcc -o test test.cpp
/tmp/ccoEdRxq.o:(.rodata._ZTI1B[typeinfo for B]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/tmp/ccoEdRxq.o:(.rodata._ZTI1A[typeinfo for A]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
/tmp/ccoEdRxq.o:(.rodata._ZTV1A[vtable for A]+0x8): undefined reference to `__cxa_pure_virtual'
collect2: ld returned 1 exit status

Мой модифицированный код выглядит следующим образом (A и B не были изменены):

class MyClass {

    public:

        void setInstance(A* newInstance) {
            instance = newInstance;
        }

        void doSomething() {
            instance->action();
        }

    private:

        A* instance;
};

int main(int argc, char** argv) {
    MyClass c;
    B myInstance;
    c.setInstance(&myInstance);
    c.doSomething();
    return 0;
}

Ответы [ 11 ]

0 голосов
/ 16 марта 2009

Вы должны использовать указатель на A как член MyClass.

class MyClass {

    public:

        void setInstance(A *newInstance) {
                instance = newInstance;
        }

        void doSomething() {
                instance->action();
        }

    private:

        A *instance;
};

если вы этого не сделаете, конструктор MyClass попытается создать экземпляр объекта A (как это было бы для любого объекта-члена), что невозможно, поскольку A является абстрактным.

...