Код копируется в производный класс?

Всякий раз, когда я получаю новый класс из базового класса, говорите:

#include <iostream>

class A {

protected:
int f;

public:

void get() {
std::cout << "The address is: "<< &f << std::endl;
}
};

class B : public A {
// ....
};

int main() {

A a;
a.get();

B b;
b.get();

return 0;
}

Адрес: 0xbfb0d5b8
Адрес: 0xbfb0d5bc

Означает ли это, что весь код из class A будет скопирован в class B? Так как у меня ничего нет в классе B то есть нет членов или функций данных Итак, когда я создаю экземпляр класса B, я обнаруживаю, что у него есть собственная переменная по другому адресу, а также функция-член. Как у него могут быть свои члены-копии, если они не скопированы?

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

Редактировать:

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

1

Решение

Код никогда не копируется во время наследования. Но когда дочерний объект (класс B) создается или создается во время выполнения, он наследует функциональность и атрибуты родительского класса / объекта (класс A).

2

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

код из класса A НЕ копируется в класс B в том смысле, что код написан только в одном месте.

однако, и здесь конусы часть многократного использования, при использовании класса b вы можете вызвать метод и использовать члены, относительно private, publicи т. д. и, следовательно, не нужно писать один и тот же код для двух классов, которые делают одно и то же

например, если у меня есть круг и квадрат, и у них обоих есть член с именем color, мне нужен метод, который его изменяет, мне не нужно писать метод и член дважды, но они должны наследовать класс Shape, который будет реализовывать один раз, и тогда они оба смогут использовать этот метод, таким образом повторно используя один метод в двух местах

1

Я не уверен, что «скопировано» является правильным словом (компилятор будет компилировать только код в class A один раз). Как вы использовали публичное наследство, class B на самом деле является особый тип class A, В качестве таких, class B имеет доступ к каждому (не частному) члену class A, поэтому код используется повторно.

Кроме того, из разговора в комментариях:

Нет. Ничего не «копируется», каждый экземпляр A и B имеет свое собственное значение для своих собственных переменных, за исключением любых статических элементов данных. Для статических членов данных, опять же, копирование не происходит; существует только одна переменная, которая является общей для всех экземпляров A а также B,

1

В вашем примере вы сравниваете два разных экземпляра двух разных классов. разные экземпляры означают разные базовые адреса для хранения данных экземпляров.

Возможно, лучшим тестом того, копируется ли поле класса в производные классы, является следующее:

#include <iostream>

class A {

protected:
int f;

public:

void get() {
std::cout << "The address is: " << &f << std::endl;
}
};

class B : public A {
// ....
};

int main() {

B b;
b.get();

A *a = &b;
a->get();

return 0;
}

И вывод:

The address is: 0x7fff41d523f0
The address is: 0x7fff41d523f0

С помощью этой программы мы можем видеть, что, хотя у нас есть экземпляр класса Bего унаследованное содержимое физически совпадает с содержимым исходного класса. A, Обратите внимание, что также возможно переопределить член класса в производном классе, но исходный член все еще будет доступен, если мы приведем экземпляр производного класса к родительскому классу (как я сделал в моем примере).

1

§1.8 (2) стандарта языка C ++ определяет, что подразумевается под субобъект:

Объекты могут содержать другие объекты, называемые субобъекты. Подобъект может быть подобъект участника (9.2), а подобъект базового класса (Пункт 10) или элемент массива. Объект, который не является подобъектом любого другого объекта, называется завершить объект.

Это примеры дочерних подобъектов и элементов массива, с которыми вы должны быть знакомы:

int a[5];
a[2]; // the third array element subobject of the complete object a

struct S { int x; }
S s;
s.x; // a member subobject of the complete object s

Это оставляет оставшийся вид подобъекта, который вас интересует: подобъекты базового класса.

struct B { int x; }
struct D : public B { int y; }

D d;
d.y; // a member subobject of the complete object d
d.x; // a member subobject of a base class subobject of the complete object d

B &b = d; // a reference to a base class subobject of the complete object d

Каждый экземпляр производного класса содержит экземпляр своего базового класса в качестве подобъекта базового класса.

1

У меня также есть некоторые сомнения относительно связи между наследованием и повторным использованием кода. Это мой взгляд на это.

Наследование — это механизм, используемый для классификации и облегчения полиморфизма. Используя наследование, мы можем построить иерархию понятий, разделенных по категориям на разных уровнях абстракции. Делая это, мы можем эффективно использовать другую концепцию ООП, полиморфизм, которая позволяет одному и тому же управляющему коду управлять всеми объектами в категории, даже если они отличаются по своей реализации.

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

0