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 内联转换为 In,我将无法访问 In 的正确值,但它可以正确访问父类(super class)型 Old 的 long val
字段(通过方法) .
gcc 版本 4.7.2 (Debian 4.7.2-5)
最佳答案
您的代码通过打印未初始化的变量导致未定义的行为。这样做的结果可能不稳定。
要解决此问题,请初始化 val
和 value
在尝试打印它们之前。 (请注意,对于虚拟继承,只有最派生的构造函数才应初始化变量)。
您没有说您不理解程序输出的哪些部分。我猜您希望最后两行输出显示相同的数字。
也许您没有意识到 (In<int>)m
从 m
复制构造一个临时对象.
行((In<int>)m).setValue(10);
创建一个临时对象,将其值设置为 10
,然后销毁临时对象。它不影响 m
.
行In<int> iv = (In<int>) m;
使 iv
成为 m
的一部分的拷贝. future 更改为 m
不会影响 iv
.当你写 iv.setValue(10)
,即更新 iv
但不是 m
.
如果要引用m
通过基类,使用 static_cast<In<int> &>(m)
. &
意思是形成一个引用,而不是按值复制。您可能还打算拥有 In<int> &iv = m;
而不是 In<int> iv = (In<int>) m;
.
关于C++ 内联转换和转换为变量的工作方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30919132/