【问题标题】:What goes on in the background when we assign Object1 = Object2 of the same class in C++?当我们在 C++ 中分配同一类的 Object1 = Object2 时,后台会发生什么?
【发布时间】:2015-02-06 02:56:07
【问题描述】:

假设两个对象(同一个类)已经被初始化了。

现在,您可以: 对象2 = 对象1;

在 Java 中,Object1 和 Object2 现在都指向同一个内存位置。

在 C++ 中会发生什么?

#include <iostream>

using namespace std;

class X {
    public:
        X() {
            cout << "Default Constructor called\n";
            i = 0;
        }
        X(int i) {
            cout << "Parameterized Constructor called\n";
            this->i = i;
        }
        X (const X& x) {
            cout << "Copy Constructor called\n";
            i = x.getI();
        }
        ~X() {
            cout << "Destructor called\n";
        }
        int getI() const {
            return i;
        }

    private:
        int i;
};

void main() {
    cout << "\nLine-1\n\n";
    X x1(1);    // On Stack
    cout << "\nLine-2\n\n";
    X* x2 = new X(2);   // On Heap
    cout << "\nLine-3\n\n";
    X x3(x1);
    cout << "\nLine-4\n\n";
    X* x4 = new X(x1);
    cout << "\nLine-5\n\n";
    X x5 = x1;
    cout << "\nLine-6\n\n";
    x5 = x3;
    cout << "\nLine-7\n\n";
    X x6 = *x2;
    cout << "\nLine-8\n\n";
    *x2 = *x4;
    cout << "\nLine-9\n\n";
    *x4 = x3;
    cout << "\nLine-10\n\n";

}

如您所见,每当我执行 createdObj1 = createdObj2 时,都不会调用任何构造函数。

【问题讨论】:

  • 它们是如何初始化的? (例如,使用新的,还是堆栈分配的?)
  • 在堆栈上,我的兄弟。
  • 复制赋值运算符被调用。编译器默认提供一个。
  • @Ben Voigt:这将我们带到下一个问题。我编写了自己的复制构造函数并有一个打印语句来知道它何时被调用,但它从未被调用过。
  • main() 应返回int

标签: c++


【解决方案1】:

函数operator=() 定义了会发生什么。它可以定义为成员函数,通常:

Object & Object::operator=(const Object &other);

如果您不提供这些函数之一,将提供默认实现,该实现对每个成员变量使用 operator=() 函数。

【讨论】:

  • operator= 必须是会员,句号。
【解决方案2】:

主要有两种情况:

当执行带有赋值的声明时,如

X x = y;

它通常(参见@T.C. 关于显式复制构造函数的评论)等价于

X x(y);

因此将简单地构造您的新对象。根本没有完成任何任务。这显然会创建一个具有自动存储持续时间的新对象x。 (如果我写的是(static X x = y; 它将具有静态存储持续时间。)

另一种情况是

x = y;

其中x 修改为等于y。这是通过调用X::operator=(X) 来完成的,其默认实现将简单地依次分配每个成员。 (自定义版本可以为所欲为。)

【讨论】:

  • 现在我明白了。谢谢你。你是个传奇。
  • 复制初始化绝不与直接初始化“完全等价”。
  • @T.C.在这种情况下,它是:“如果初始化是直接初始化,或者如果它是复制初始化,其中源类型的 cv 非限定版本与目标类的类相同或派生类, 构造函数被考虑。[...]"
  • @gha.st 由于被称为显式复制构造函数的疯狂,它们仍然不等价。
猜你喜欢
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 2014-11-13
  • 2013-04-18
  • 1970-01-01
相关资源
最近更新 更多