полиморфизм — виртуальные классы c ++: интересный момент

Скажите, пожалуйста, почему вывод такой, как показано ниже для следующей программы. Я не получаю виртуальные классы в C ++. соблюдайте следующий код:

class B
{
public:
B(char c = 'a') : m_c(c) {}

public:
char get_c() const { return m_c; }
void set_c(char c) { m_c = c; }

private:
char m_c;
};

class C: public B
{ };

class D: public B
{ };

class E
: public C
, public D
{ };

int main()
{
E e;
C &c = e;
D &d = e;
std::cout << c.get_c();
d.set_c('b');
std::cout << c.get_c() << std::endl;
return 0;
}

O / P: аа
Я ожидаю, что выход будет AB. Что было бы причиной для получения «аа» ??

Если у меня есть c.set_c (‘b’) вместо d.set_c (‘b’), тогда я получу O / P: «ab». Здесь также я не понимаю, почему это так. Оба c, d относятся только к одному объекту.

class C:virtual public B{};
class D:virtual public B{};

Если класс C, класс D унаследованы практически от B, то
O / P всегда будет «ab»

5

Решение

рассматривать class C : public B а также C* c = new C затем c указать на хранилище, которое начинается с B поскольку C* это также B*, а это true за class D : public B,

Теперь для class E : public C, public D а также E* e = new E(), память о e это что-то вроде:

{| B of C | other members of C }{| B of D | other members of D}

как вы можете видеть в приведенном выше случае у нас есть 2 экземпляра B один для C и еще один для D и теперь это очевидно, когда вы звоните ((D*)e)->set_c( 'b' ) ты только меняешься B экземпляр D а также B экземпляр C останется без изменений.

теперь, когда вы говорите class C : public virtual B, C ++ поделиться B экземпляр с любым другим классом, который практически наследует от B, так что в этом случае e это что-то вроде:

           | shared B |
| C members | | D members |

и, как вы можете видеть, у нас есть только один B так зовет ((C*)e)->set_c а также ((D*)e)->set_c оба будут действовать на то же B,

1

Другие решения

Есть две копии B в Eодин через C и один через D, Когда вы звоните d.set_c('b')модифицируешь m_c в D«s B, Когда вы звоните c.get_c(), тогда вы получите m_c в C«s B, который не изменился.

Когда вы делаете C а также D наследовать от B практически, это решает проблему, потому что тогда есть только одна копия B в E,

Это актуально: http://www.parashift.com/c++-faq/virtual-inheritance-where.html

9

Я не уверен, что понимаю проблему, но ваш вопрос содержит ответ, объявите B как виртуальную базу для C и D, и вы получите.

#include <iostream>

class B
{
public:
B(char c = 'a') : m_c(c) {}

public:
char get_c() const { return m_c; }
void set_c(char c) { m_c = c; }

private:
char m_c;
};

// note virtual inheritance
class C: virtual public B
{ };

// note virtual inheritance
class D: virtual public B
{ };

class E
: public C
, public D
{ };

int main()
{
E e;
C &c = e;
D &d = e;
std::cout << c.get_c() << std::endl;;
d.set_c('d');
std::cout << c.get_c() << std::endl;
c.set_c('c');
std::cout << d.get_c() << std::endl;
return 0;
}

что приводит к желаемому результату, не так ли?

a
d
c
1
По вопросам рекламы [email protected]