C++赋值运算符关于继承的问题

发布于 2024-11-03 11:38:29 字数 200 浏览 2 评论 0原文

我有两个类 - 基类 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

后来的我们 2024-11-10 11:38:29
class Base
{
    //Members       
};

class Derived1:public Base
{
    //Members
};

class Derived2:private Base
{
    //Members 
};


int main()
{
    Base obj1;
    Derived1 obj2;
    Derived2 obj3;

    obj1 = obj2;   //Allowed Since Public Inheritance 
    obj1 = obj3;   //Not Allowed, Compiler generates error
}

当 obj1 = obj2 时,仅将从基类继承的派生类 obj2 的成员复制到 obj1,派生类的其余成员将被删除。这只是因为基类 obj1 不知道派生类的成员。这种现象称为对象切片

如果类有需要在堆上分配的指针成员变量,则 obj1 = obj2 会创建一个浅复制,这意味着 obj1 和 obj2 中的指针成员变量现在将指向相同的堆内存。那么如果 obj2 被操作系统回收并且 obj1 仍在使用中会发生什么呢?灾难!因此,应该通过重载 = 运算符和创建对象的深复制来避免浅复制。

class Base
{
    //Members       
};

class Derived1:public Base
{
    //Members
};

class Derived2:private Base
{
    //Members 
};


int main()
{
    Base obj1;
    Derived1 obj2;
    Derived2 obj3;

    obj1 = obj2;   //Allowed Since Public Inheritance 
    obj1 = obj3;   //Not Allowed, Compiler generates error
}

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 called Object Slicing.

If the class have pointer member variables which need allocation on Heap, then obj1 = obj2 creates a Shallow 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 by overloading = operatorand making a Deep copy of objects.

眼前雾蒙蒙 2024-11-10 11:38:29

这当然是允许的。它将把 obj2A 子对象分配给 obj

由于 IS-A 关系,如果不阻止 A 实例的赋值,几乎不可能在编译时阻止这种情况。

This is certainly allowed. It will assign the A subobject of obj2 to obj.

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.

夜司空 2024-11-10 11:38:29

它将浅复制 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.

始终不够 2024-11-10 11:38:29

重载你的赋值运算符。并且在实现 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

尤怨 2024-11-10 11:38:29
A::operator=(const A& value);

将被执行。 obj1 隐式转换 (static_cast) 为 const A&

因此,您的 obj=obj1; 相当于

obj = static_cast<const A&>(obj1);

显然隐式生成的赋值将分配 A 的每个非静态成员。

要拒绝这种情况,请使用私有/受保护的继承。通过使用公共继承,您声称所有 B 类型的对象都可以以各种可能的方式合法地用作 A 类型的对象。

您还可以显式声明

A& A::operator=( const B& value );

或者定义

A& A::operator=( const A& value );

以多态方式运行。

A::operator=(const A& value);

will be executed. obj1 implicitly cast (static_cast) to const A&.

So your obj=obj1; is equivalent to

obj = static_cast<const A&>(obj1);

Obviously 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

A& A::operator=( const B& value );

Or you also may define

A& A::operator=( const A& value );

to behave in polymorphic way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文