2015-07-23 2 views
1

Я хочу знать, почему эта функция печатает «aba h()», а не «son h()» из-за ее виртуального. Я подумал, что, возможно, функция скрывает другую функцию, но имеет такую ​​же подпись.виртуальная функция не входит в базовый класс

class Aba: public Saba { 
public: 
    Aba(){cout << "Aba Ctor" << endl;} 
    Aba(const Aba& a){cout << "Aba Copy Ctor" << endl;} 
    ~Aba(){cout << "Aba Dtor" << endl;} 
    virtual void g(){cout << "Aba g()" << endl;} 
    virtual void f(int){cout << "Aba f(int)" << endl;} 
    virtual void h(){cout << "Aba h()" << endl;} 
}; 

class Son: public Aba { 

public: 
    Son(){cout << "Son Ctor" << endl;} 
    Son(const Son& a){cout << "Son Copy Ctor" << endl;} 
    ~Son(){cout << "Son Dtor" << endl;} 
    void f(){cout << "Son f()" << endl;} 
    void h(){cout << "Son h()" << endl;} 
}; 

главная:

int main() 

{ 
    Aba aba = Aba(); 
    aba.h(); 

    return 0; 

} 
+0

Это явная цель виртуальных функций. Создавая 'Aba', вызов' h() 'разрешает' Aba :: h'. Виртуальные функции знают о созданном типе. Не виртуальная функция - нет. –

+2

Зачем это печатать «Сын»? Вы вообще не ссылаетесь на «Сын» в 'main()'. –

+0

@JohnKugelman вы входите в виртуальную часть сына только тогда, когда есть ссылка? – jaldk

ответ

0

virtual метод решаться на основе типа объекта идет речь. В вашем случае тип объекта всегдаAba, потому что даже если вы назначили Son(), объект нарезается до Aba. Следовательно, он печатает метод Aba::h().

Runtime динамическое связывание возможно со ссылками & указатели. В нижеследующих случаях он напечатает Son::h().

Son s; 
Aba& r = s; 
r.h(); // r referres to Son 
Aba* p = &r; // or &s 
p->h(); // p points/referred to Son 
0

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

Aba && one = Aba(); 
// static type: reference to Aba 
// dynamic type of referenced object: Aba 

Таким образом, виртуальная функция решает функцию определяется как член Aba.

Aba && two = Son(); 
// static type: reference to Aba 
// dynamic type of referenced object: Son 

Теперь виртуальная функция рассосется к определению в Son, предполагая, что есть такое определение.

1

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

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

Aba *ptr = new Son; 
ptr->h(); //Ptr is pointing to Son, hence Son::h() will get called. 
Смежные вопросы