2012-08-29 4 views
0

Следующий код не компилируется, но я не могу понять ошибку:тест Полиморфизма не работает

#include <iostream> 

class FamilyMember { 

    int age; 
    public: 
    virtual int myage() = 0; 
}; 


class Grandfather: public FamilyMember { 

    int age; 
    public: 
    Grandfather(): age(60) { 
     std::cout << "Im grandpa" << std::endl; 
    } 
    ~Grandfather() { 
     std::cout << "Oh no! Grandpa is dead!" << std::endl; 
    } 
    virtual int myage() const { 
     return age; 
    } 
}; 


class Father: public Grandfather { 

    int age; 
    public: 
    Father(): age(40) { 
     std::cout << "Im papa" << std::endl; 
    } 
    ~Father() { 
     std::cout << "Papa is gone, noooooo!" << std::endl; 
    } 
    virtual int myage() const { 
     return age; 
    } 
}; 


class Son: public Father { 

    int age; 
    public: 
    Son(): age(20) { 
     std::cout << "Im the kid" << std::endl; 
    } 
    ~Son() { 
     std::cout << "Son is dead? He was so young!" << std::endl; 
    } 
    int myage() const { 
     return age; 
    } 
}; 

int main() { 

    Grandfather G; 
    Father F; 
    Son S; 

    return 0; 
} 

Здесь находятся ошибки я получаю (я вырублен код до минимального количества, которое нарушает его, так номера строк не совпадают).

main.cc:535: error: cannot declare variable ‘G’ to be of abstract type ‘Grandfather’ 
main.cc:161: note: because the following virtual functions are pure within ‘Grandfather’: 
main.cc:157: note: virtual int FamilyMember::myage() 
main.cc:536: error: cannot declare variable ‘F’ to be of abstract type ‘Father’ 
main.cc:177: note: because the following virtual functions are pure within ‘Father’: 
main.cc:157: note: virtual int FamilyMember::myage() 
main.cc:537: error: cannot declare variable ‘S’ to be of abstract type ‘Son’ 
main.cc:193: note: because the following virtual functions are pure within ‘Son’: 
main.cc:157: note: virtual int FamilyMember::myage() 
make: *** [main.o] Error 1 
Compilation failed. 
+0

Вы знаете о тот факт, что у Деда и Отца действительно есть два члена, называющих возраст?Один унаследован от FamilyMember и их собственный? – sellibitze

+0

Итак, у меня тогда не было 'int age' на' FamilyMember'? Технически, из того, что вы сказали, «отец» должен иметь ** трех ** членов, называемых тогда возрастом. Один из своих, один из «Деда» и один из «Семейного члена», нет? –

+1

Справа. То, что вы должны делать, зависит от того, чего вы пытаетесь достичь. Я не вижу смысла в этих отношениях наследования. У каждого члена семьи есть возраст, и это единственный атрибут, который у вас есть. Итак, зачем беспокоиться о создании этого отношения наследования? Не злоупотребляйте наследованием. – sellibitze

ответ

6

Различные подписи.

virtual int myage() = 0; 

И в детских классах.

virtual int myage() const 

Сделать pure-virtualmyageconst тоже, или сделать non-const эту функцию в Чайлдс.

+0

Спасибо. Теперь, если я хотел напечатать возраст «Отца» с объекта «Сын», как мне это сделать? В основном, мой вопрос: как я могу вызвать функцию 'myage()' '' Father' из объекта 'Son'? –

+1

@curvature Father :: myage() в функции объекта Son. – ForEveR

+0

И что, если у меня есть функция 'void PrintMyAge (const FamilyMember * f) {std :: cout << f-> myage() << std :: endl; } 'и на главном у меня был« Сын ». Как я могу называть «PrintMyAge (s)» таким образом, чтобы на самом деле печатать возраст отца? –

0

Вы не используете myage правильно.

virtual int myage() = 0;

это не то же самое, как

virtual int myage() const

const по методу сделает другой подписи, и, таким образом, другой метод

0

Это объявляется чистая виртуальная в базе

virtual int myage() = 0; 

но в производном классе прототип функции

virtual int myage() const 

это другая функция, и поэтому ваша неконстантная версия в базовом классе не было отменено, и ошибка компилятор говорит вам об этом.

0

Функция myage в классе «FamilyMember» и «Дед» имеет разную подпись.

virtual int myage() = 0; // В FamilyMember

и

виртуального ИНТ туАд() сопзИте // В Деде

Попробуйте изменить определение класса FamilyMember следующего класса FamilyMember {

int age; 
public: 
virtual int myage() const = 0; 
}; 
0

Также было бы сделать больше смысла не давать каждому подклассу атрибут age, просто используйте тот, у которого есть суперкласс.

class FamilyMember 
{ 
    protected: 
     int age; 
    public: 
     virtual int myage() const = 0; 
     FamilyMember(int a) : age(a) {} 
}; 

class Grandfather: public FamilyMember 
{ 
    public: 
     Grandfather(): FamilyMember(60) {} 
     ~Grandfather() {} 
     virtual int myage() const { return FamilyMember::age; } 
}; 
1

В дополнение к тому, что было сказано во всех других ответов, C++ 11 предоставляет специальный идентифицированный override, который будет иметь указатель на ошибку во время компиляции:

class Grandfather: public FamilyMember { 

    // as before ... 

    virtual int myage() const override { // Error! Not overriding. 
     return age; 
    } 
}; 
Смежные вопросы