复制构造函数和赋值运算符

发布于 2024-10-24 14:50:24 字数 115 浏览 3 评论 0原文

如果我覆盖 operator= 复制构造函数会自动使用 new 运算符吗?同样,如果我定义一个复制构造函数,operator= 会自动“继承”复制构造函数的行为吗?

If I override operator= will the copy constructor automatically use the new operator? Similarly, if I define a copy constructor, will operator= automatically 'inherit' the behavior from the copy constructor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(6

探春 2024-10-31 14:50:25

不会。除非您定义复制因子,否则将生成默认值(如果需要)。除非您定义运算符=,否则将生成默认值(如果需要)。它们不互相使用,您可以单独更改它们。

No. Unless you define a copy ctor, a default will be generated (if needed). Unless you define an operator=, a default will be generated (if needed). They do not use each other, and you can change them independently.

白云悠悠 2024-10-31 14:50:25

不,它们是不同的对象。

如果您担心复制构造函数和赋值运算符之间的代码重复,请考虑以下习惯用法,名为 复制和交换

struct MyClass
{
    MyClass(const MyClass&); // Implement copy logic here
    void swap(MyClass&) throw(); // Implement a lightweight swap here (eg. swap pointers)

    MyClass& operator=(MyClass x)
    {
        x.swap(*this);
        return *this;
    }
};

这样,operator= 将使用复制构造函数构建一个新对象,该对象将与 交换*this 并在函数退出时释放(其中包含旧的 this)。

No. They are different objects.

If your concern is code duplication between copy constructor and assignment operator, consider the following idiom, named copy and swap :

struct MyClass
{
    MyClass(const MyClass&); // Implement copy logic here
    void swap(MyClass&) throw(); // Implement a lightweight swap here (eg. swap pointers)

    MyClass& operator=(MyClass x)
    {
        x.swap(*this);
        return *this;
    }
};

This way, the operator= will use the copy constructor to build a new object, which will get exchanged with *this and released (with the old this inside) at function exit.

水中月 2024-10-31 14:50:25

,一定要看看三法则
(或五规则考虑右值时)

No.

And definitely have a look at the rule of three
(or rule of five when taking rvalues into account)

九公里浅绿 2024-10-31 14:50:25

考虑以下 C++ 程序。
注意:我的“Vector”类不是标准库中的类。
我的“Vector”类接口

#include <iostream>

class Vector {
private:
    double* elem; // elem points to an array of sz doubles
    int sz;
public:
    Vector(int s);  // constructor: acquire resources
    ~Vector() { delete[] elem; }   // destructor: release resources
    Vector(const Vector& a);               // copy constructor
    Vector& operator=(const Vector& a);    // copy assignment operator
    double& operator[](int i){ return elem[i]; };
    int size() const {return sz;};
};

我的“Vector”类成员实现

Vector::Vector(int s)  // non-default constructor
{
    std::cout << "non-default constructor"<<std::endl;
    elem = {new double[s]};
    sz =s;
    for (int i=0; i!=s; ++i)      // initialize elements
        elem[i]=0;
}

Vector::Vector(const Vector& a)   // copy constructor
        :elem{new double[a.sz]},
         sz{a.sz}
{
    std::cout << "copy constructor"<<std::endl;
    for (int i=0; i!=sz; ++i)    // copy elements
        elem[i] = a.elem[i];
}

Vector& Vector::operator=(const Vector& a)     // copy assignment operator
{
    std::cout << "copy assignment operator"<<std::endl;
    double* p = new double[a.sz];
    for (int i=0; i!=a.sz; ++i)
        p[i] = a.elem[i];
    delete[] elem;         // delete old elements
    elem = p;
    sz = a.sz;
    return *this;
}

int main(){
    Vector v1(1);
    v1[0] = 1024;    // call non-default constructor
   
    Vector v2 = v1;   // call copy constructor  !!!!

    v2[0] = 1025;
    std::cout << "v2[0]=" << v2[0] << std::endl;

    Vector v3{10};  // call non-default constructor
    std::cout << "v3[0]=" << v3[0] << std::endl;

    v3 = v2;     // call copy assignment operator  !!!!
    std::cout << "v3[0]=" << v3[0] << std::endl;
}

然后,程序输出:

non-default constructor
copy constructor
v2[0]=1025
non-default constructor
v3[0]=0
copy assignment operator
v3[0]=1025

总结

  1. Vector v2 = v1; 导致调用复制构造函数。
  2. v3 = v2; 导致调用复制赋值运算符。

在情况 2 中,对象 v3 已经存在(我们已经完成:Vector v3{10};)。复制构造函数和复制赋值运算符有两个明显的区别。

  • 复制构造函数不需要删除旧元素,它只是复制构造一个新对象。 (如Vector v2
  • 复制构造函数不需要返回this指针。(此外,所有构造函数都不返回值)。

Consider the following C++ program.
Note: My "Vector" class not the one from the standard library.
My "Vector" class interface:

#include <iostream>

class Vector {
private:
    double* elem; // elem points to an array of sz doubles
    int sz;
public:
    Vector(int s);  // constructor: acquire resources
    ~Vector() { delete[] elem; }   // destructor: release resources
    Vector(const Vector& a);               // copy constructor
    Vector& operator=(const Vector& a);    // copy assignment operator
    double& operator[](int i){ return elem[i]; };
    int size() const {return sz;};
};

My "Vector" class members implementation:

Vector::Vector(int s)  // non-default constructor
{
    std::cout << "non-default constructor"<<std::endl;
    elem = {new double[s]};
    sz =s;
    for (int i=0; i!=s; ++i)      // initialize elements
        elem[i]=0;
}

Vector::Vector(const Vector& a)   // copy constructor
        :elem{new double[a.sz]},
         sz{a.sz}
{
    std::cout << "copy constructor"<<std::endl;
    for (int i=0; i!=sz; ++i)    // copy elements
        elem[i] = a.elem[i];
}

Vector& Vector::operator=(const Vector& a)     // copy assignment operator
{
    std::cout << "copy assignment operator"<<std::endl;
    double* p = new double[a.sz];
    for (int i=0; i!=a.sz; ++i)
        p[i] = a.elem[i];
    delete[] elem;         // delete old elements
    elem = p;
    sz = a.sz;
    return *this;
}

int main(){
    Vector v1(1);
    v1[0] = 1024;    // call non-default constructor
   
    Vector v2 = v1;   // call copy constructor  !!!!

    v2[0] = 1025;
    std::cout << "v2[0]=" << v2[0] << std::endl;

    Vector v3{10};  // call non-default constructor
    std::cout << "v3[0]=" << v3[0] << std::endl;

    v3 = v2;     // call copy assignment operator  !!!!
    std::cout << "v3[0]=" << v3[0] << std::endl;
}

Then, the program output:

non-default constructor
copy constructor
v2[0]=1025
non-default constructor
v3[0]=0
copy assignment operator
v3[0]=1025

To wrap up:

  1. Vector v2 = v1; lead to call copy constructor.
  2. v3 = v2; lead to call copy assignment operator.

In case 2, Object v3 already exists (We have done: Vector v3{10};). There are two obvious differences between copy constructor and copy assignment operator.

  • copy constructor NO NEED to delete old elements, it just copy construct a new object. (as it Vector v2)
  • copy constructor NO NEED to return the this pointer.(Furthermore, all the constructor does not return a value).
请爱~陌生人 2024-10-31 14:50:25

不,他们不是同一个运营商。

No, they are not the same operator.

汹涌人海 2024-10-31 14:50:24

不,他们是不同的运营商。

复制构造函数用于创建一个新对象。它将现有对象复制到新构造的对象。复制构造函数用于从旧实例初始化新实例
实例。当将变量按值传递给函数时不一定会调用它
或作为函数的返回值。

赋值运算符是处理一个已经存在的对象。赋值运算符用于更改现有实例以使其具有
与右值相同的值,这意味着该实例必须是
如果它有内部动态内存,则被销毁并重新初始化。

有用的链接:

No, they are different operators.

The copy constructor is for creating a new object. It copies an existing object to a newly constructed object.The copy constructor is used to initialize a new instance from an old
instance. It is not necessarily called when passing variables by value into functions
or as return values out of functions.

The assignment operator is to deal with an already existing object. The assignment operator is used to change an existing instance to have
the same values as the rvalue, which means that the instance has to be
destroyed and re-initialized if it has internal dynamic memory.

Useful link :

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