C++;:将我的对象强制转换到不同的超类会导致不同的指针地址 我学习C++,试图编写好的、多态的代码,并运行到一些混乱。我有一个类Er_1Sine,它有两个超类:“Generator”和“Triggerable”

C++;:将我的对象强制转换到不同的超类会导致不同的指针地址 我学习C++,试图编写好的、多态的代码,并运行到一些混乱。我有一个类Er_1Sine,它有两个超类:“Generator”和“Triggerable”,c++,inheritance,pointers,polymorphism,C++,Inheritance,Pointers,Polymorphism,Er_1Sine看起来像这样: class Er_1Sine : public Generator, public Triggerable{ } 如果我创建一个“生成器”指针(gen),将其设置为“er1”,指针地址将与“er1”的地址匹配。但是,我的“Triggerable”指针“trig”的地址不匹配。这是怎么回事?trig是否与er1和gen指向的对象不同 er1 = new Er_1Sine(); Generator *gen = er1; Triggerable *trig

Er_1Sine看起来像这样:

class Er_1Sine : public Generator, public Triggerable{

}
如果我创建一个“生成器”指针(gen),将其设置为“er1”,指针地址将与“er1”的地址匹配。但是,我的“Triggerable”指针“trig”的地址不匹配。这是怎么回事?trig是否与er1和gen指向的对象不同

er1 = new Er_1Sine();   
Generator *gen = er1;
Triggerable *trig = er1;

printf("\n\n er1 as Er_1Sine: %p \n", er1);
// outputs: "er1 as Er_1Sine: 0x4d28920"

printf("er1 as Generator address: %p \n", gen);
// outputs: "er1 as Generator address: 0x4d28920"   

printf("er1 as Triggerable address: %p \n\n", trig);
// outputs: er1 as Triggerable address: 0x4d289f8

这是多重继承-基类子对象与子实例的偏移量不同,因此地址不同。编译器前端必须在隐式向上转换期间调整指针值。

一个指针指向类的
生成器部分,另一个指针指向类的
触发器部分。它们不能是同一个指针,因为Generator和Triggerable是不同的。

通过多重继承,不同的基类在子对象中可以有不同的内存地址。

虽然不完全正确,但您可以将复合类视为两个相互堆叠的独立对象。您首先声明的是顶部(相同地址),其次声明的是底部(因此是不同的地址)。

我还要补充一点,正是出于这个原因,您可能不应该对指针值执行==来确定相等性。可能最好采用类似Java的方法,编写一个相等函数或运算符。嗯,是和否。比较指针是一个内置操作,您不能重写它。比较实例很可能需要一组自定义运算符。没有什么比这更像Java了……:)实际上,使用==表示指针相等对于确定它们是否指向同一对象来说通常是非常好的,因为如果我正确地阅读了标准,指针只能在它们是相同类型时进行比较(在可能的类型转换之后),因此在本例中,当比较基类指针和派生类指针时,后者将隐式转换为基类(并因此进行相应调整),因此,如果两者都来自同一个派生对象,则将比较true。@Grizzly在过去,我曾在一个函数内部与==和!=被称为(崩溃并不是发生在比较中,而是在随后的逻辑中)。我想我说话太鲁莽了。我经常进行ptr==比较,但如果在API函数中我无法控制调用上下文,我宁愿采用编写类成员的方法来确定相等性。此函数可以在派生类中隐藏,但不应为虚拟函数。不过,这也会变得很混乱,因为派生函数需要记住调用父相等函数。@Grizzly,没有什么可以说的,您不能比较对象部分的相等,而不能比较macocosmic相等函数。显然,这取决于每个用例。