C++赋值运算符关于继承的问题
我有两个类 - 基类 A 和派生类 B - 我写了这个
A obj;
B obj2;
obj = obj2;
如果我还没有覆盖任何赋值运算符,实际上会发生什么?这只是将 obj2 的 A 部分复制到 obj 中吗?这是正确的,还是编译器只是借口的错误? IS_A 关系是否允许执行该语句?非常感谢任何帮助。
I have two classes - base class A and derived class B - and I write this
A obj;
B obj2;
obj = obj2;
What would actually happen if I have yet to overide any assigment operators? Would this just copy the A part of obj2 into obj? Is this even proper, or a error that the compiler just excuses? Does a IS_A relationship permit this statement to execute? Any help is greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当 obj1 = obj2 时,仅将从基类继承的派生类 obj2 的成员复制到 obj1,派生类的其余成员将被删除。这只是因为基类 obj1 不知道派生类的成员。这种现象称为
对象切片
。如果类有需要在堆上分配的指针成员变量,则 obj1 = obj2 会创建一个浅复制,这意味着 obj1 和 obj2 中的指针成员变量现在将指向相同的堆内存。那么如果 obj2 被操作系统回收并且 obj1 仍在使用中会发生什么呢?灾难!因此,应该通过
重载 = 运算符
和创建对象的深复制
来避免浅复制。When
obj1 = obj2
only those members of the Derived Class obj2 that are inherited from Base Class get copied in to obj1, rest of the members of Derived Class get sliced off. This is simply because Base class obj1 is not aware of members of Derived class. This phenomemon is calledObject Slicing
.If the class have pointer member variables which need allocation on Heap, then
obj1 = obj2
creates aShallow Copy
, which means the pointer member variable inside obj1 and obj2 will now point to the same heap memory. So What happens if obj2 is reclaimed by the OS and obj1 is still in use? Disaster! So shallow copies should be avoided byoverloading = operator
and making aDeep copy
of objects.这当然是允许的。它将把
obj2
的A
子对象分配给obj
。由于 IS-A 关系,如果不阻止 A 实例的赋值,几乎不可能在编译时阻止这种情况。
This is certainly allowed. It will assign the
A
subobject ofobj2
toobj
.Due to the IS-A relationship, it is pretty much impossible to prevent this at compile time without also preventing assignment from an instance of A.
它将浅复制 obj2 的“A”部分。
从语言的角度来看,这是完全可以的。
如果它适合您的应用程序,这取决于许多因素,但这就是您可以重载赋值运算符的原因。
It would shallow copy the "A" part of the obj2.
It is perfectly OK from the language standpoint.
If it is OK for your app, that depends on many factors, but that is why you can overload the assignment operator.
重载你的赋值运算符。并且在实现 B 部分时,A 部分中的 thts 将被分配...在您尝试分配 A 中存在的 B 值之前,不会生成编译器错误
overload your assignment operator. and in mplementation B part thts in A part will be assigned... no compiler error will be generated till u try to assign values of B that exist in A
将被执行。
obj1
隐式转换 (static_cast) 为const A&
。因此,您的 obj=obj1; 相当于
显然隐式生成的赋值将分配 A 的每个非静态成员。
要拒绝这种情况,请使用私有/受保护的继承。通过使用公共继承,您声称所有
B
类型的对象都可以以各种可能的方式合法地用作 A 类型的对象。您还可以显式声明
或者定义
以多态方式运行。
will be executed.
obj1
implicitly cast (static_cast) toconst A&
.So your
obj=obj1;
is equivalent toObviously implicitly generated assignment will assign every non-static member of
A
.To deny this use private/protected inheritance. By using public inheritance you claim that all objects of type
B
may be legitimately used as objects of type A in every possible way.You also may explicitly declare
Or you also may define
to behave in polymorphic way.