Разница в адресе базовых и производных объектов с использованием *, по сравнению с использованием оператора &
Может кто-нибудь попытаться объяснить мне, почему я получаю разницу в адресе базового и производного объекта при использовании этого указателя и оператора &. Ниже мой код
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"Base Address "<<this<<endl;
}
};
class B:public A
{
public:
B()
{
cout<<"Deri Address "<<this<<endl;
}
};
int main()
{
B b;
}
The O/P is
Base Address 0x7fff500e9bdf
Deri Address 0x7fff500e9bdf
Оба одинаковы.
Когда я добавлю еще два утверждения в основном, как показано ниже
#include <iostream>
использование пространства имен std;
class A
{
public:
A()
{
cout<<"Base Address "<<this<<endl;
}
};
class B:public A
{
public:
B()
{
cout<<"Deri Address "<<this<<endl;
}
};
int main()
{
B b;
A a;
cout<<&a<<endl<<&b<<endl;
}
O/P как показано ниже
Base Address 0x7fff82c696df
Deri Address 0x7fff82c696df
Base Address 0x7fff82c696de
0x7fff82c696de
0x7fff82c696df
Теперь я мог ясно видеть, что адрес отличается
а) в чем может быть причина этой разницы
б) Еще одна вещь, которую я хотел бы знать, является ли базовый подобъект в производном классе точно таким же, как базовый объект? Я запутался в этом, потому что если мы говорим в базовом классе, есть ли у нас переменная x, и если у нас есть производный класс для этого базового класса (неполиморфный случай), теперь, если мы говорим о базовом субобъекте в производном, является ли он тот же самый x, присутствующий в базовом классе, также присутствует в базовом подобъекте производного класса (я имею в виду переменную с одинаковым адресом в базовом и базовом подобъекте в производном), или у нас есть отдельная копия x как в базовом, так и в базовом подобъекте производного (я имею в виду переменную с другим адресом)
Please clarify?
3 ответа
Почему вы получаете то, что видите? ну это потому что a != b
Вы создаете 2 объекта:
A a;
B b;
Это ясно, если вы добавите еще один параметр в конструктор вашего класса А.
class A
{
public:
A(std::string name)
{
cout<<name<<"'s Base Address "<<this<<endl;
}
};
и измените свой main
функционировать немного
int main()
{
B b("b");
A a("a");
cout<<"a: "<<&a<<endl<<"b: "<<&b<<endl;
}
Теперь ваш вывод будет выглядеть так
b's Base Address 0x7fff82c696df
b's Deri Address 0x7fff82c696df
a's Base Address 0x7fff82c696de
a: 0x7fff82c696de
b: 0x7fff82c696df
Теперь вы можете видеть, что результат & operator
а также *this
равны. Вы просто буксируете разные объекты, конечно же, с двумя разными адресами. Вы также видите, что для производного класса B
, this
имеет такое же значение в B
с и A
конструктор
У вас есть два объекта: a и b:
с адресом 0x7fff82c696de
б с адресом 0x7fff82c696df
Я думаю, что первое, что нужно прояснить для вас, это понимание различия между классом и объектом. Класс является планом, тогда как объект является экземпляром класса.
Таким образом, если вы не создадите экземпляр класса, у вас ничего не останется в памяти.
В первом случае напечатанные адреса совпадают, потому что вы создали один экземпляр. Имеет смысл иметь один и тот же адрес из-за наличия только одного единственного объекта.
Во втором случае адреса различаются из-за наличия двух разных объектов (создаются два экземпляра класса), а не из-за использования &
, Итак, следующий код печатает те же адреса.
#include <iostream>
class A
{
public:
A() { std::cout << "Address with this pointer: " << this << std::endl; }
};
int main()
{
A a;
std::cout << "Address with & operator: " << &a << std::endl;
}
Изменить: почему представляет один и тот же адрес для подобъекта
Как я уже упоминал в комментариях, я никогда не слышал термин подобъект. Но я получил ниже определение здесь.
подобъект: Любой объект, который хранится в другом объекте (элементы массива, объекты базового класса и объекты-члены данных).
Объект естественным образом занимает память, и любой подобъект объекта должен находиться где-то в этой памяти. Первый созданный подобъект (с точки зрения порядка определения) получает первую часть памяти, второй созданный подобъект получает вторую часть памяти сразу после первого объекта и так далее. Итак, первый созданный подобъект имеет тот же начальный адрес, что и сам объект. В следующем коде созданный первый объект является экземпляром класса A (поэтому A и C имеют один и тот же адрес) только потому, что класс A наследуется раньше, чем класс B. Если вы измените class C : public A, public B
в class C : public B, public A
тогда объекты класса B и класса C будут одинаковыми.
#include <iostream>
class A
{
public:
A() { std::cout << "Address of Sub-Object A: " << this << std::endl; }
int x;
};
class B
{
public:
B() { std::cout << "Address of Sub-Object B: " << this << std::endl; }
int y;
};
class C : public A, public B {
public:
C() : A() , B() { std::cout << "Address of Object C: " << this << std::endl; }
int z;
};
int main()
{
C c;
}
PS: если вы думаете о композиции, а не о наследовании, то это может быть проще для понимания.