Переопределенная функция C ++ не вызывается

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

В файлах obj1.h / obj1.cpp у меня что-то вроде этого

class obj1{
public:
    void print();
};

void obj1::print(){
    cout << "obj1::print()";
}

В файлах obj2.h / obj2.cpp у меня что-то вроде этого:

#include "obj1.h"   
class obj2 : public obj1{
public:
    void print();
};

void obj2::print(){
    cout << "obj2::print()";
}

В отдельных файлах делаю примерно так:

#include "obj1.h"   
class obj3{    
public:
    vector<obj1*> objlist;
    void printobjs();
    void addobj(obj1* o);
};

void obj3::printobjs(){
    vector<obj1*>::iterator it;
    for (it=objList.begin(); it < objList.end(); it++)
        (*it)->print();

void obj3::addobj(obj1* o){
    objlist.push_back(o);
}

Затем в другом файле:

#include "obj2.h"
obj3 o3;
main(){
    obj2* newobj2;
    newobj2 = new obj2();
    o3.addobj(newobj2);

    o3.printobjs();

Моя проблема в том, что printobjs () вызывает вызов obj1.print (). (Я немного поискал и прочитал несколько десятков сообщений с проблемами перегрузки, но не нашел похожей проблемы)

Может ли кто-нибудь указать мне в этом правильном направлении? Спасибо!


person M F    schedule 26.11.2015    source источник
comment
Функции должны быть virtual для того, что вы хотите.   -  person πάντα ῥεῖ    schedule 26.11.2015


Ответы (3)


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

Вы должны сделать print виртуальным:

class obj1{
public:
    virtual void print();
};

Затем, если вы используете C ++ 11, в целях безопасности вы можете пометить obj2::print как override:

class obj2 : public obj1{
public:
    void print() override;
};

Также обратите внимание, что вы никогда не выделяете память для newobj2.

person TartanLlama    schedule 26.11.2015

Вы должны объявить print() как виртуальный для вызова obj2 :: print () для объектов obj2.

virtual void print();
person Yuriy Orlov    schedule 26.11.2015

Я не совсем уверен, это время журнала, так как я работал с С ++, но, насколько я помню, вы должны иметь содержимое векторов в виде классов с чистыми виртуальными функциями.

Это должно заставить его искать правильный метод.

Здесь есть ответ о переполнении стека, который немного связан:

Чистый виртуальный класс и коллекции (вектор?)

person user2692263    schedule 26.11.2015
comment
Нет необходимости в чисто виртуальных функциях. - person πάντα ῥεῖ; 26.11.2015
comment
Спасибо - так что все на месте. Я получил просветление здесь: stackoverflow.com/questions/1306778/ - person user2692263; 26.11.2015