首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用*this与使用&运算符的基对象和派生对象的地址差异

使用*this与使用&运算符的基对象和派生对象的地址差异
EN

Stack Overflow用户
提问于 2018-11-28 19:38:01
回答 3查看 122关注 0票数 0

有人能解释一下为什么在使用这个指针和&运算符时,基对象和派生对象的地址会有差异吗?下面是我的代码

代码语言:javascript
运行
复制
#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

两者都是一样的。

当我在main中再添加两个语句时,如下所示

代码语言:javascript
运行
复制
#include <iostream>

使用命名空间std;

代码语言:javascript
运行
复制
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如下所示

代码语言:javascript
运行
复制
Base Address 0x7fff82c696df
Deri Address 0x7fff82c696df
Base Address 0x7fff82c696de
0x7fff82c696de
0x7fff82c696df

现在我可以清楚地看到地址不同了。

a)造成这种差异的原因是什么?

b)我想知道的另一件事是派生类中的基子对象是否与基对象完全相同?我对此感到困惑,因为如果我们说在基类中,如果我们有一个变量x,如果我们有一个基类的派生类(非多态情况)如果我们现在讨论派生类中的基子对象,那么基类中存在的相同x是否也存在于派生类的基子对象中(我是指在派生类的基对象和基子对象中具有相同地址的变量),或者我们在派生的基子对象和基子对象中都有x的单独副本(我是指具有不同地址的变量)

代码语言:javascript
运行
复制
Please clarify?
EN

回答 3

Stack Overflow用户

发布于 2018-11-28 19:46:01

您有两个对象:ab

地址为0x7fff82c696de的A

地址为0x7fff82c696df的B

票数 1
EN

Stack Overflow用户

发布于 2018-11-28 19:48:49

为什么你会得到你所看到的?嗯,这是因为a != b,你创建了两个对象:

代码语言:javascript
运行
复制
A a;
B b;

如果您将另一个参数添加到类A的构造函数中,则会清除此问题

代码语言:javascript
运行
复制
class A
{
    public:
     A(std::string name)
     {
         cout<<name<<"'s Base Address "<<this<<endl;
     }
};

并稍微修改一下您的main函数

代码语言:javascript
运行
复制
int main()
{
    B b("b");
    A a("a");
   cout<<"a: "<<&a<<endl<<"b: "<<&b<<endl;

}

现在您的输出将如下所示

代码语言:javascript
运行
复制
b's Base Address 0x7fff82c696df
b's Deri Address 0x7fff82c696df
a's Base Address 0x7fff82c696de
a: 0x7fff82c696de
b: 0x7fff82c696df

现在你可以看到& operator*this的结果是相等的。你只需要两个不同的对象,当然,有两个不同的地址。您还可以看到,对于派生类BthisB的构造函数和A的构造函数中具有相同的值。

票数 1
EN

Stack Overflow用户

发布于 2018-11-28 20:03:57

我认为首先要澄清的是理解object之间的区别。是一个蓝图,而object是该类的一个实例。

因此,如果不创建类的实例,那么内存上就什么也没有了。

在第一种情况下,打印的地址是相同的,因为您创建了一个实例。因为只有一个对象,所以具有相同的地址是有意义的。

在第二种情况下,地址不同是因为有两个不同的对象(创建了类的两个实例),而不是因为使用了&。因此,下面的代码打印相同的地址。

代码语言:javascript
运行
复制
#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;
}

编辑:为什么表示子对象的相同地址

正如我在评论中提到的,我从来没有听说过子对象这个术语。但是我从here得到了下面的定义。

子对象:存储在另一个对象(数组元素、基类对象和数据成员对象)中的任何对象。

对象自然会占用内存,并且对象的任何子对象都需要位于内存中的某个位置。第一个创建的子对象(根据定义顺序)获取内存的第一部分,第二个创建的子对象获取紧跟在第一个对象之后的第二部分内存,依此类推。因此,第一个创建的子对象具有与对象本身相同的起始地址。在下面的代码中,第一个创建的对象是A类的实例(因此A和C具有相同的地址),因为A类先于B类被继承。如果将class C : public A, public B更改为class C : public B, public A,则类B和类C的对象将是相同的。

代码语言:javascript
运行
复制
#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:如果你考虑的是组合而不是继承,那么它可能更容易理解。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53518567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档