C++ 为什么虚拟功能会破坏我的角色?
我正在努力扩展以下代码:C++ 为什么虚拟功能会破坏我的角色?,c++,casting,virtual,downcast,C++,Casting,Virtual,Downcast,我正在努力扩展以下代码: #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 { s
#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;
}
#包括
类XmlTree{};
阶级基础
{
受保护的:
int-var;
公众:
Base(int-var):var(var){}
虚拟~Base(){}
};
派生类:公共基
{
公众:
void SerializeTo(XmlTree&tree)const{std::coutb
不是派生的
对象,因此将其强制转换为派生的
是未定义的行为
在第一个示例中,正确的解决方案是将序列化方法移动到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;
}
#包括
类XmlTree{};
阶级基础
{
受保护的:
int-var;
公众:
Base(int-var):var(var){}
虚拟~Base(){}
虚拟空序列化为(XmlTree&tree)常量=0;
虚拟void反序列化自(const-XmlTree&tree)=0;
};
派生类:公共基
{
公众:
派生(int-var):基(var){}
void SerializeTo(XmlTree&tree)const override{std::coutb
不是派生的
对象,因此将其强制转换为派生的
是未定义的行为
在第一个示例中,正确的解决方案是将序列化方法移动到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;
}
#包括
类XmlTree{};
阶级基础
{
受保护的:
int-var;
公众:
Base(int-var):var(var){}
虚拟~Base(){}
虚拟空序列化为(XmlTree&tree)常量=0;
虚拟void反序列化自(const-XmlTree&tree)=0;
};
派生类:公共基
{
公众:
派生(int-var):基(var){}
void序列化为(XmlTree&tree)常量重写{std::cout当定义b
为Base
类型时,调用操作符当定义b
为Base
类型时,调用操作符b
不是派生的
对象,因此将其强制转换为派生的
是未定义的行为。添加虚拟的
帮助y使存在的问题变得明显。这不是问题的原因。b
不是派生的
对象,因此将其强制转换为派生的
是未定义的行为。添加虚拟的
有助于使存在的问题变得明显。这不是问题的原因。遗憾的是,更改“Base”不是一个选项。@PanicSheep:那么你呢除非您选择XmlInterface
路线,否则您的运气不好。您最初显示的代码将不起作用,您需要按照说明更正设计。遗憾的是,更改“Base”不是一个选项。@PanicSheep:那么您就运气不好,除非您选择XmlInterface
路线。您最初显示的代码将不起作用,您需要更正按所述纠正设计。
#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;
}