为什么虚拟功能打破了我的铸造
Why does a virtual function break my casting?
我正在努力扩展以下代码:
#include <iostream>
class XmlTree {};
class Base
{
protected:
int var;
public:
Base(int var) : var(var) {}
virtual ~Base() {}
};
class Derived : public Base
{
public:
void SerializeTo(XmlTree& tree) const { std::cout << var << std::endl; }
void DeserializeFrom(const XmlTree& tree) { var = 2; }
};
void operator<<(XmlTree& tree, const Base& b) { static_cast<const Derived&>(b).SerializeTo(tree); }
void operator>>(const XmlTree& tree, Base& b) { static_cast<Derived&>(b).DeserializeFrom(tree); }
int main() {
Base b(1);
XmlTree tree;
tree << b;
tree >> b;
tree << b;
}
此代码正常运行,并按照预期打印'1',然后打印'2'。
但是现在我想实现这样的接口:
class XmlInterface
{
public:
virtual void SerializeTo(XmlTree& tree) const = 0;
virtual void DeserializeFrom(const XmlTree& tree) = 0;
};
class Derived : public Base, public XmlInterface
{
public:
virtual void SerializeTo(XmlTree& tree) const override { std::cout << var << std::endl; }
virtual void DeserializeFrom(const XmlTree& tree) override { var = 2; }
};
tl; dr:如何使它起作用?
我试图使用Dynamic_cast和虚拟破坏者来制作类多态性。我还试图实现从基地到派生的解释降低的构造函数,但我失败了。
ps:更改"基础"不是一个选择。
b
不是 Derived
对象,因此将其施放给Derived
是不确定的行为。
在第一个示例中,正确的解决方案是将序列化方法移动到Base
中,并使它们虚拟/抽象使Derived
可以覆盖它们。然后创建一个Derived
对象,然后从操作员中删除铸件:
#include <iostream>
class XmlTree {};
class Base
{
protected:
int var;
public:
Base(int var) : var(var) {}
virtual ~Base() {}
virtual void SerializeTo(XmlTree& tree) const = 0;
virtual void DeserializeFrom(const XmlTree& tree) = 0;
};
class Derived : public Base
{
public:
Derived(int var) : Base(var) {}
void SerializeTo(XmlTree& tree) const override { std::cout << var << std::endl; }
void DeserializeFrom(const XmlTree& tree) override { var = 2; }
};
void operator<<(XmlTree& tree, const Base& b) { b.SerializeTo(tree); }
void operator>>(const XmlTree& tree, Base& b) { b.DeserializeFrom(tree); }
int main() {
Derived d(1);
XmlTree tree;
tree << d;
tree >> d;
tree << d;
}
在第二个示例中做类似的事情:
#include <iostream>
class XmlTree {};
class Base
{
protected:
int var;
public:
Base(int var) : var(var) {}
virtual ~Base() {}
};
class XmlInterface
{
public:
virtual void SerializeTo(XmlTree& tree) const = 0;
virtual void DeserializeFrom(const XmlTree& tree) = 0;
};
class Derived : public Base, public XmlInterface
{
public:
Derived(int var) : Base(var) {}
void SerializeTo(XmlTree& tree) const override { std::cout << var << std::endl; }
void DeserializeFrom(const XmlTree& tree) override { var = 2; }
};
void operator<<(XmlTree& tree, const XmlInterface& intf) { intf.SerializeTo(tree); }
void operator>>(const XmlTree& tree, XmlInterface& intf) { intf.DeserializeFrom(tree); }
int main() {
Derived d(1);
XmlTree tree;
tree << d;
tree >> d;
tree << d;
}
将b
定义为Base
类型和调用操作员<<
时,将操作数施加到Derived&
时,您会产生未定义的行为,因为b
不是Derived
类型。未定义的行为意味着一切都会发生,包括按预期工作的程序。更改设置可以产生不同的"未定义行为",这就是您可以观察到的。
相关文章:
- 我可以调用从 main() 覆盖的虚拟函数吗?
- 为什么在这种情况下不调用我的虚拟函数实现?
- 为什么我只能在 4 GB 的虚拟内存空间上分配 2 GB?
- 为什么我的虚拟破坏者多次执行这些执行
- 我可以在 ANTLR4 中使用类似于 c++ 的虚拟令牌(具有相同返回值的令牌)吗?
- 我如何确保从我的派生类中调用纯虚拟方法
- 为什么虚拟功能打破了我的铸造
- 我能补充子类的虚拟函数吗
- getPeername()在客户端在虚拟机上运行时返回我的本地主机地址
- 我如何调用基类的虚拟函数定义,这些定义在Ampract Base类和C 中的派生类中都有定义
- 当我在派生类中添加额外的虚拟功能时,什么是开销
- 在这种情况下,我的派生类是否还需要一个虚拟析构函数
- 当我的基类和派生类具有相同的函数时,它必须是虚拟的吗?
- 我是否只需要基类中的虚拟
- 如何确定为我的程序保留了多少虚拟内存
- 为什么我的输出流seg出错,而我的虚拟析构函数不起作用,但当我杀死虚拟的时候,它起作用了
- 我可以拥有一个必须从非抽象基重写的虚拟函数吗
- 为什么当我从虚拟基数派生 D 时,VS2015 中的 sizeof(D) 增加了 8 个字节
- 我正在使用放置新功能和虚拟功能;为什么我的虚拟功能表有误?
- 我的虚拟函数无法C++工作