C ++ наследуют виртуальные функции - PullRequest
4 голосов
/ 26 мая 2011

хорошо, скажем, у нас есть следующие классы

class A
{
public:
    virtual void taco()
    {
        cout << "Class A" << endl;
    }
};
class B: public A
{
    public:
    virtual void taco()
    {
        cout << "Class B" << endl;
    }
};
class C : public A
{
    public:
    void taco()
    {
        cout << "Class C" << endl;
    }
};

Теперь, если я сделаю это

A a = A();
B b = B();
C c = C();
a.taco(); //Class A
b.taco(); //Class B
c.taco(); //Class C
deque<A> aa = deque<A>();
aa.push_back(a);
aa.push_back(b);
aa.push_back(c);
for(int i=0;i<aa.size();i++)
    aa[i].taco();//All Class A
A r = B();
r.taco(); //Class A

Теперь вы заметите, когда я инициализирую A как B или C, он победит 'Я запускаю функции из B или C. Мне было интересно, есть ли способ обойти это?Я понимаю концепцию, что, поскольку объект является A, он использует функцию taco A, но мне было просто интересно, есть ли какой-то трюк для получения доступа к другим функциям.Мой проект довольно сложный, и я не могу знать все классы, которые будут переопределять A (из-за плагинов, переопределяющих класс).Кроме того, мне нужно, чтобы базовая виртуальная функция имела тело для добавления поведения по умолчанию.Спасибо.

1 Ответ

15 голосов
/ 26 мая 2011

Вы должны хранить указатели в deque, так как полиморфизм работает только с ссылочными и указательными типами. Когда вы вставляете эти объекты в deque, копии создаются типа A, «обрезая» части, которые сделали их B или C изначально.

Аналогично, A r = B() просто создает временный B и копирует A его часть в A с именем r.

Кстати A a = A(); вы могли бы также написать A a;. Они не полностью эквивалентны, но они выполняют ту же самую работу здесь, и вы, вероятно, имели в виду более простую версию.

A a;
B b;
C c;
a.taco(); //Class A
b.taco(); //Class B
c.taco(); //Class C

// With pointers and containers
deque<A*> aa;
aa.push_back(&a);
aa.push_back(&b);
aa.push_back(&c);
for (int i=0; i<aa.size(); i++)
    aa[i]->taco(); // Hurray!    

// With refs
B q;
A& r = q;
r.taco(); // Class B!

(Просто помните, что эти объекты a, b и c имеют автоматическую продолжительность хранения. В тот момент, когда они выходят из области видимости, если deque все еще существует, все его элементы являются недействительными указателями. Я хочу использовать динамическое распределение для дальнейшего управления временем жизни объектов A, B и C ... но я оставлю это в качестве упражнения для читателя.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...