Действительно ли наследование приводит к тому, что члены класса «наследуются»? - PullRequest
0 голосов
/ 17 марта 2012

От ответ на Наследование: почему существует разница в поведении между унаследованными и предоставленными переменными? , я понимаю, что приведенный ниже код печатает 0, потому что есть только один копия x.

#include<iostream>
using namespace std;

class A {
    public:
        int x;
        A() { x = 10; }
};

class B : public A {
    public:
        B() { x = 0; }
};

int main() {
    A* ab = new B;
    cout << ab->x << endl; // prints 0
}

Но разве это не противоречит самому значению наследования?

Я закодировал class B для публичного перехода от class A и ожидал, что он унаследует копию переменной-члена x, что должно было привести к ab->x печатному значению 10 .

Что мне здесь не хватает? Мне трудно понять, почему это печатает 0 несмотря на наследование.

Ответы [ 5 ]

4 голосов
/ 17 марта 2012

Вот простая фигура, которая кратко объясняет наследование в терминах переменных-членов:

enter image description here

Когда создается ChildClass, BaseClass создается и существует внутриДетский класс.Переменные a, b и c могут быть доступны как из ChildClass, так и Baseclass (в зависимости от модификаторов доступа, таких как public, private и protected). Они передаются, а не копируются .

1 голос
/ 17 марта 2012

inherit a copy of member variable x - ну, он не наследует копию , он просто наследует переменную. и это сделал.

Сначала запускается конструктор A (x = 10), конструктор B (x = 0). После этого x, очевидно, 0.

Основываясь на вашем комментарии, я думаю, что вы ищете состав , а не наследование :

class B {
   public:
     A a;
     int x;
};
1 голос
/ 17 марта 2012

Я ожидал, что он унаследует копию переменной-члена x

Нет, вы не наследуете при копировании.B наследование A приводит к тому, что каждый объект B содержит подобъект типа A.Поскольку x определено в A, вы модифицируете подобъект A, присвоив x.

Следующая переформулировка кода делает этот подобъект видимым:

#include <iostream>

using namespace std;

struct A {
  int x;
  A() { x = 10; }
};

struct B {
  A subobject;
  B(): subobject() { this->subobject.x = 0; }
};

int main() {
  B* ab = new B;
  cout << ab->subobject.x << endl; // prints 0
}

Это, конечно, не идентично наследованию, так как типы A и B теперь больше не связаны (вы не можете конвертировать из B в A), но это несколько аналогично тому, что компилятор видит, когдавы используете наследство.

0 голосов
/ 17 марта 2012

Или, иначе говоря, для члена x не существует неявного 0 или 10.Что происходит, происходит потому, что вы вызываете конструктор B с помощью вызова new.Не имеет значения, определен ли x в A или в B или как глобальная переменная.Конструктор B устанавливает его в 0, поэтому он равен 0.

Помогает ли это?

0 голосов
/ 17 марта 2012

B наследует x от A (со значением 10, установленным в конструкторе A), но затем немедленно устанавливает его в 0 в своем собственном конструкторе.

Существует толькоодин x, общий для A и B.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...