C++ C++;在基本对象std::swap之后,派生对象数据是否保证有效?
这样做安全吗:C++ C++;在基本对象std::swap之后,派生对象数据是否保证有效?,c++,swap,object-slicing,C++,Swap,Object Slicing,这样做安全吗: class Base { public: int x; }; class Derived : public Base { public: int y; }; Base b; Derived d; b.x = 1; d.x = 2; d.y = 3; std::swap(b,d); 此时是否保证派生信息d.y仍然有效?换句话说,我只是交换基本对象,但派生数据仍然有效,对吗?还有,这算是切片吗 编辑:在评论中指出这不会编译。用b交换d中的基础数据的最佳方法是什么?请记住,b显然比我
class Base { public: int x; };
class Derived : public Base { public: int y; };
Base b;
Derived d;
b.x = 1;
d.x = 2;
d.y = 3;
std::swap(b,d);
此时是否保证派生信息d.y仍然有效?换句话说,我只是交换基本对象,但派生数据仍然有效,对吗?还有,这算是切片吗
编辑:在评论中指出这不会编译。用b交换d中的基础数据的最佳方法是什么?请记住,b显然比我的例子要复杂得多。这取决于你对valid的定义以及问题范围的精确程度。在一般情况下,仅交换基是无效的,因为派生类型可能强制执行其他可能被破坏的不变量
在没有不变量的特定情况下,所有公共数据(在修复类型定义以便下面的代码编译之后)都将被交换,并且很可能不会引起任何问题(假设:交换中的更改可以通过直接访问成员手动完成,因此
交换不会破坏任何不会被破坏的内容)。不…编译…模板std::swap(T&,T&)
看到模式了吗?x
和y
是私有的…您不能在类范围之外访问它们…它不会编译…@PierreFourgeaud即使您将字段公开,swap
声明为使用相同类型的参数。@jrok我知道,我只是想再添加一个理由,说明它不会编译。您需要使用std::swap(b,static_cast(d));
进行编译(正如jrok指出的)。你能举一个可能被破坏的其他不变量的例子吗?我不知道你的确切意思。如果我从派生类中交换基础数据,我是否也交换了它的虚拟函数?但是,请注意,如果一个类因为可以自由访问基类而被破坏,那就是该类中的一个bug。@user2672807:不,你是只是更改数据(虚拟函数不会更改)。但是派生类型上的函数可能取决于基成员和添加的数据成员中的值的特定组合(不变量,如派生成员x
始终保持基成员a
和b
的总和)。问题中的交换可能会通过修改完整对象的部分而不更新其余部分来打破这些不变量。@GManNickG:同意,尽管我担心大多数代码基在这里会失败(考虑到继承通常是如何被滥用的)。David和@GManNickG好的,我会考虑到这一点,谢谢大家。