2014-01-08 7 views
-1

В C++ я не могу понять, когда указатель базового класса хранит адрес объекта производного класса, он не может вызвать функцию-член производного класса?Виртуальная функция, как они работают?

#include <iostream> 
using namespace std; 

class Base 
{ 
public: 
    virtual void show() 
    { 
     cout<<" In Base "; 
    } 
}; 

class Derived: public Base 
{ 
public: 
    int x; 
    void show() 
    { 
     cout<<"In Derived "; 
    } 
    Derived() 
    { 
     x = 10; 
    } 
}; 

int main(void) 
{ 
    Base *bp, b; 
    Derived d; 
    bp = &d; 
    bp->show(); 
    cout << bp->x; 
    return 0; 
} 

По мне: derived d => выделяет память для этого объекта (следовательно, х также) сказать, по адресу 200, bp = &d; => она выделена по адресу 200 до п.н.. Теперь он должен иметь возможность называть bp-> x? Но это дает ошибку.

+0

возможно дубликат [поведение виртуальной функции в C++] (HTTP: // StackOverflow .com/questions/2669681/behavior-of-virtual-function-in-c) –

+6

Этот вопрос, похоже, не о виртуальных функциях, а о Base, не имеющий члена, называемого x. – PlasmaHH

ответ

1

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

Ну да, вы можете, вам просто нужно привести указатель на класс, где переменная член присутствует

cout << dynamic_cast<Derived*>(bp)->x; 
+0

По мне d => выделяет память этому объекту (поэтому для x также) говорят по адресу 200, bp = & d; => он выделил адрес 200 в bp. Теперь он должен иметь возможность называть bp-> x? –

+1

Экземпляр 'Derived' содержит' x', но указатель, который вы используете, имеет тип Base, поэтому вы не можете использовать его для доступа к x (прямолинейно). С точки зрения памяти вы правы, что «x» есть –

+0

, мы можем также вызвать класс funtion класса, используя тип casting. Если да, вы можете сказать мне синтаксис, спасибо. –

2

bp->x выдает ошибку, потому что bp является указателем на объект типа Base и Base не имеет переменную x, только Derived делает.

Если x был переведен в Base он будет доступен как из Base и Derived если это публично или защищен.

+0

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

+0

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

+0

Нет, компилятор знает, что он имеет тип 'Base' и что он имеет функцию' show() '. Он ничего не знает о классах, которые наследуются от него. – PomfCaster

0

Почему bp-> x является ошибкой?

Потому что во время компиляции компилятор не может сказать, на что указывает. Что, если это было на самом деле, указатель на базовый класс? Тогда x будет полностью отсутствовать от объекта, ...

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

2

Связывание имен происходит во время выполнения. поэтому при компиляции bp имеет тип базы. поэтому компилятор ничего не знает о назначении производного типа. поэтому его высказывание не содержит переменной, называемой x в базе.

Вот где понятие виртуальных функций входит в картину. но они предназначены только для функций, а не переменных.

Смежные вопросы