继承中的对象比较
object comparison in inheriance
在下面的代码中,使用==比较两个对象显示的输出与比较两个字符指针的输出不同。请告诉我它是如何工作的。
#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;
}
输出:136
为什么y的值是3而z的值是6。这里到底发生了什么。
const int y = (pb == &c) ? 3 : 4;
相当于使用
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))
该表达式的值将是false
您正在使用多重继承。在这种情况下,当您创建派生类的实例时,通常会发生以下情况:
- 为所有基类和派生类保留足够的内存来保存数据。
-
在内存中布局基类数据的顺序是您为派生类指定的继承顺序。对于您的情况:
class C: public A, public B
对象的内存布局如下:A数据成员,B数据成员,C数据成员。
在您的例子中,pa和pb实际上指向不同的地址,但由于比较期间的隐式转换,y被赋值为3。但是,通过对char*进行重新解释强制转换,您将带走允许编译器进行隐式强制转换的信息。相反,会进行普通的指针比较,结果为false。
如果你这样做 C* pc = &c;
并检查调试器中PC的值,您会注意到它与突出显示上述点的pa相同。
将对象'c'的地址传递给类A的指针'pa';指向b类的指针'pb'
为'pa' &&'pb'保存了指向类c的对象'c'的相同内存,因此变量x的表达式&
对于z变量的表达式,您比较'pa'和'pb'的地址,迫使它们解释为强制转换char指针,但这两个指针可能在内存中的两个不同位置分配,因此它们不匹配,您得到z=6(即false)
相关文章:
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- C++ <algorithm> 使用对象作为比较定义的 sort()
- C++,如何使用常量对象和非常量对象进行比较?
- 绘制一个对象,比较模具缓冲区的两个不同值
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- 为什么地图需要实现'operator<'以及如何比较对象?
- 如何使用std::lower_bound比较对象变量,而不使用第二个对象进行比较
- 可作为常量调用的比较对象
- 如何为C++映射创建自己的字符串比较对象
- 如何用类别的consumetrized构造函数声明使用类的比较对象设置的STL设置
- 我可以防止 std::sort 复制传递的比较对象吗?
- 是否可以创建一个函数来比较对象向量中动态选择的变量
- 比较对象的3个数字属性
- 如何将比较对象或函数传递给类函数
- C++STL priority_queue,比较对象的方法
- 比较对象标识符与字符串
- c++ STL集合:比较对象与外部状态
- 比较对象和指针
- 比较对象的两个向量的元素
- c++比较对象