Я действительно смущен. Я побежал в следующей ситуации, где С наследуется от А и В, но в зависимости от того, как вещи назначены, я получаю другое поведение:Доступ к члену производного класса из указателя базового класса
Если бы я
new
вC
экземпляр, и хранить его вA
указатель , а затем присвоить это значение кB
указателя, и вызов методаA
с помощьюA
указателя, и способB
сB
указателем, я получаю странные вещи ... (см Test 1).Если я
new
вC
экземпляр, и хранить его вC
указатель, а затем присвоить это значение указателяA
иB
, и вызов методаA
с помощьюA
указателя, и способB
сB
указатель, я получаю то, что ожидаю ... (см. Тест 2).
Мой вопрос: Почему тест 1 ведет себя так, как он делает?
Класс A
class A
{
public:
A() { aMember = 'A'; }
virtual ~A() {}
virtual char getAMember() { return aMember; }
private:
char aMember;
};
Класс B
class B
{
public:
B() { bMember = 'B'; }
virtual ~B() {}
virtual char getBMember() { return bMember; }
private:
char bMember;
};
Класс C
class C : public A, public B
{
public:
C() : A(), B() {}
virtual ~C() {}
};
Главное, что имеет Test1 & Test2
#include <cstdio>
int main(void)
{
C* c;
A* a;
B* b;
printf("Test 1\n");
a = new C();
b = (B*)a;
printf("a->getAMember(): %c\n",a->getAMember()); // prints A
printf("b->getBMember(): %c\n",b->getBMember()); // prints A ?!
printf("Test 2\n");
c = new C();
a = c;
b = c;
printf("a->getAMember(): %c\n",a->getAMember()); // prints A
printf("b->getBMember(): %c\n",b->getBMember()); // prints B
return 0;
}
Опасная вещь о приведении указателя заключается в том, что компилятор позволит вам это сделать, даже если это не имеет смысла. –
Вы также можете прочитать следующее сообщение: http://stackoverflow.com/questions/9374244/casting-pointer-to-base-class-into-a-pointer-to-derived-class –