0

有人可以尝试解释一下为什么我在使用这个指针和 & 运算符时会在基址和派生对象的地址上有所不同。下面是我的代码

#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 中添加另外两个语句时,如下所示

#include <iostream>

使用命名空间标准;

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

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

a) 这种差异的原因可能是什么
b) 我想知道的另一件事是派生类中的基础子对象是否与基础对象完全相同?我对此感到困惑,因为如果我们在基类中说如果我们有一个变量 x 并且如果我们有这个基类的派生类(非多态情况)现在如果我们在派生中谈论基子对象,它是基类中存在的相同 x 也存在于派生类的基子对象中(我的意思是派生的基子对象和基子对象中具有相同地址的变量),或者我们在基子对象和基子对象中都有一个单独的 x 副本派生的(我的意思是具有不同地址的变量)

Please clarify?
4

3 回答 3

1

你有两个对象:ab

一个地址为 0x7fff82c696de

b 地址为 0x7fff82c696df

于 2018-11-28T11:46:01.383 回答
1

为什么你得到你所看到的?好吧,这是因为a != b 您确实创建了 2 个对象:

A a;
B b;

如果您向 A 类的构造函数添加另一个参数,它会明确

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和的 thr 结果*this相等。当然,您只需使用两个不同的地址来拖曳不同的对象。您还看到,对于派生类B,在s 和s 构造函数this中具有相同的值。BA

于 2018-11-28T11:48:48.983 回答
0

我认为首先要为您澄清的是理解classobject之间的区别。类是蓝图,而对象是类的实例

因此,如果您不创建该类的实例,那么您的内存中将一无所有。

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

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

#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;
}

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

正如我在评论中提到的,我从未听说过sub-object这个词。但我从这里得到了以下定义。

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

一个对象自然会占用一个内存,并且该对象的任何子对象都需要位于该内存的某个位置。第一个创建的子对象(根据定义顺序)获得内存的第一部分,第二个创建的子对象在第一个对象之后获得内存的第二部分,依此类推。因此,第一个创建的子对象与对象本身具有相同的起始地址。在下面的代码中,第一个创建的对象是Class A的实例(所以 A 和 C 具有相同的地址),因为Class AClass B更早被继承。如果更改class C : public A, public Bclass 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:如果你考虑组合而不是继承,那么它可能更容易理解。

于 2018-11-28T12:03:56.697 回答