C++ 内在的客体比较
在下面的代码中,使用==比较两个对象与比较两个字符指针显示不同的输出。请帮助我了解它的工作原理C++ 内在的客体比较,c++,operators,C++,Operators,在下面的代码中,使用==比较两个对象与比较两个字符指针显示不同的输出。请帮助我了解它的工作原理 #include <iostream> class A { public: A() : m_i(0) { } protected: int m_i; }; class B { public: B() : m_d(0.0) { } protected: double m_d; }; class C : public A
#include <iostream>
class A
{
public:
A() : m_i(0) { }
protected:
int m_i;
};
class B
{
public:
B() : m_d(0.0) { }
protected:
double m_d;
};
class C
: public A
, public B
{
public:
C() : m_c('a') { }
private:
char m_c;
};
int main()
{
C c;
A *pa = &c;
B *pb = &c;
const int x = (pa == &c) ? 1 : 2;
const int y = (pb == &c) ? 3 : 4;
const int z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)) ? 5 : 6;
std::cout << x << y << z << std::endl;
return 0;
}
#包括
甲级
{
公众:
A():m_i(0){}
受保护的:
国际货币基金组织;
};
B类
{
公众:
B():mud(0.0){}
受保护的:
双m_d;
};
C类
:公众A
,公共图书馆
{
公众:
C():m_C('a'){}
私人:
charm_c;
};
int main()
{
C C;
A*pa=&c;
B*pb=&c;
常数int x=(pa==&c)?1:2;
常数y=(pb==&c)?3:4;
const int z=(重新解释铸造(pa)=重新解释铸造(pb))?5:6;
标准::cout
相当于使用
B *pb2 = &c;
const int y = (pb == bp2) ? 3 : 4;
当将&c
与B*
进行比较时,它会自动转换为B*
,这会偏移c
的地址,以匹配c
的B
部分。这就是表达式(pb=&c)
计算结果为true
的原因
但是,pa
和pb
是不同的地址。因此,当您使用
(reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb))
(重新解释投射(pa)=重新解释投射(pb))
该表达式的值将为false
相当于使用
B *pb2 = &c;
const int y = (pb == bp2) ? 3 : 4;
当将&c
与B*
进行比较时,它会自动转换为B*
,这会偏移c
的地址,以匹配c
的B
部分。这就是表达式(pb=&c)
计算结果为true
的原因
但是,pa
和pb
是不同的地址。因此,当您使用
(reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb))
(重新解释投射(pa)=重新解释投射(pb))
如果将对象“c”的地址传递给类A的指针“pa”和类B的指针“pb”,则该表达式的值将为false
由于“pa”和“pb”拥有与类c的对象“c”引用的相同内存,所以变量x&y的表达式为true
对于z变量的表达式,比较“pa”和“pb”的地址,迫使它们解释为cast char指针,但这两个指针可能分配在内存中的两个不同位置,因此它们不匹配,得到z=6(即false)将对象“c”的地址传递给类a的指针“pa”和类B的指针“pb”
由于“pa”和“pb”拥有与类c的对象“c”引用的相同内存,所以变量x&y的表达式为true
对于z变量的表达式,您将“pa”的地址与“pb”的地址进行比较,迫使它们解释为cast char指针,但这两个指针可能已分配到内存中的两个不同位置,因此它们不匹配,您得到z=6(即false)您正在使用多重继承。在这种情况下,当您创建派生类的实例时,通常会发生以下情况:
- 保留足够的内存来保存所有基类和派生类的数据
- 基类数据在内存中的排列顺序是您为派生类指定的继承顺序。对于您的情况:
C类:公共A、公共B
对象的内存布局如下所示:A数据成员、B数据成员和C数据成员
在您的例子中,pa和pb实际上指向不同的地址,但由于比较过程中的隐式转换,y被赋值为3。但是通过对字符*进行重新解释强制转换,您带走了允许编译器进行隐式强制转换的信息。相反,进行了普通指针比较,结果为false
如果你这样做
C*pc=&C;
并在debugger中检查pc的值,您会注意到它与突出显示上述要点的pa相同。您正在使用多重继承。在这种情况下,当您创建派生类的实例时,通常会发生以下情况:
- 保留足够的内存来保存所有基类和派生类的数据
- 基类数据在内存中的排列顺序是您为派生类指定的继承顺序。对于您的情况:
C类:公共A、公共B
对象的内存布局如下所示:A数据成员、B数据成员和C数据成员
在您的例子中,pa和pb实际上指向不同的地址,但由于比较过程中的隐式转换,y被赋值为3。但是通过对字符*进行重新解释强制转换,您带走了允许编译器进行隐式强制转换的信息。相反,进行了普通指针比较,结果为false
如果你这样做
C*pc=&C;
在debugger中检查pc的值,您会注意到它与pa相同,这突出了上面的一点。谢谢您的输入。请尝试打印pa、pb和c的地址。我认为pa和pb不一样。这就是我所说的,pa和pb在不同的位置有不同的地址和c,但值存储在指针pa和pb中引用相同的地址,即c的地址。因此,第一个和第二个表达式为真,而第三个表达式为假。存储在pa和pb中的值是不同的。@Saravanan,你不明白。看,pa和pb是两个指针,它们在物理位置(即c的地址)中存储了相同的值。但它们也存储在不同的位置ons。谢谢您的输入。请尝试打印pa、pb和c的地址。我认为pa和pb不一样。这就是我所说的,pa和pb在不同的位置有不同的地址和c,但指针pa和pb中存储的值指的是相同的地址,即c的地址。因此,第一个和第二个表达式为真,而第三个表达式为假值在这里,pa和pb是不同的。@Saravanan,你不明白。看,pa和pb是两个指针,它们的物理位置(即c的地址)中存储了相同的值。但它们都是