class Old
{
protected:
long val;
public:
long myVal()
{
return val;
}
void myVal(long val)
{
this->val = val;
}
};
template<typename T> class In: virtual public Old
{
protected:
T value;
public:
void setValue(T val)
{
value = val;
}
T getValue()
{
return value;
}
};
class My: public In<int>, public In<bool>
{
};
int main(int argc, char **argv)
{
My m;
m.myVal(100);
In<int> iv = (In<int>) m;
std::cout << "start_ils: " << ((In<int>)m).getValue() << std::endl;
std::cout << "start_vs: "<< iv.getValue() << std::endl;
((In<int>)m).setValue(10);
std::cout << "=== old's val ===" << std::endl;
std::cout << "old_vs: "<<iv.myVal() << std::endl;
std::cout << "old_ilsi: " << ((In<int>)m).myVal() << std::endl;
std::cout << "old_ilsb: " << ((In<bool>)m).myVal() << std::endl;
std::cout << "=== set_ils ===" << std::endl;
std::cout << "get_ils: " << ((In<int>)m).getValue() << std::endl;
std::cout << "get_vs: "<< iv.getValue() << std::endl;
iv.setValue(10);
std::cout << "=== set_vs ===" << std::endl;
std::cout << "get_ils: " << ((In<int>)m).getValue() << std::endl;
std::cout << "get_vs: "<< iv.getValue() << std::endl;
}
此代码生成此输出:
start_ils: -2126649320
start_vs: -2126649320
=== old's val ===
old_vs: 100
old_ilsi: 100
old_ilsb: 100
=== set_ils ===
get_ils: -2126649320
get_vs: -2126649320
=== set_vs ===
get_ils: -2126649320
get_vs: 10
如果我在内联或首次输入变量时将My转换为In来访问int getValue()
,那么有何不同之处?
看起来它访问坏段但更奇怪的是,如果我进行内联投射My to In我无法访问In的正确值但它正确访问超类型Old {{1} } field(槽方法)。
gcc 4.7.2版(Debian 4.7.2-5)
答案 0 :(得分:2)
您的代码通过打印未初始化的变量导致未定义的行为。结果可能不稳定。
要解决此问题,请在尝试打印之前初始化val
和value
。 (请注意,对于虚拟继承,只有最派生的构造函数才能初始化变量。)
您没有说出您不理解程序输出的哪些部分。我猜你期望最后两行输出显示相同的数字。
也许您并不知道(In<int>)m
从m
复制构造临时对象。
行((In<int>)m).setValue(10);
创建一个临时对象,将其值设置为10
,然后销毁临时对象。它不会影响m
。
In<int> iv = (In<int>) m;
行使iv
成为m
部分的副本。对m
的未来更改不会影响iv
。当您撰写iv.setValue(10)
时,会更新iv
,但不会更新m
。
如果您想通过基类引用m
,请使用static_cast<In<int> &>(m)
。 &
表示形成引用,而不是按值复制。您可能还打算使用In<int> &iv = m;
代替In<int> iv = (In<int>) m;
。