减少operator=和复制构造函数之间的代码重复

发布于 2024-08-06 16:07:22 字数 71 浏览 5 评论 0原文

我有一个需要非默认复制构造函数和赋值运算符的类(它包含指针列表)。有没有通用的方法来减少复制构造函数和赋值运算符之间的代码重复?

I have a class that requires a non-default copy constructor and assignment operator (it contains lists of pointers). Is there any general way to reduce the code duplication between the copy constructor and the assignment operator?

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

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

发布评论

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

评论(4

樱花坊 2024-08-13 16:07:22

没有编写适用于所有情况的自定义复制构造函数和赋值运算符的“通用方法”。但有一个习语称为“复制和交换”:

 class myclass
 {
    ...
 public:
    myclass(myclass const&);

    void swap(myclass & with);

    myclass& operator=(myclass copy) {
        this->swap(copy);
        return *this;
    }

    ...
};

它在许多(但不是所有)情况下都很有用。有时你可以做得更好。如果向量或字符串足够大,则可以进行更好的分配,重用分配的存储空间。

There's no "general way" for writing custom copy constructors and assignment operators that works in all cases. But there's an idiom called "copy-&-swap":

 class myclass
 {
    ...
 public:
    myclass(myclass const&);

    void swap(myclass & with);

    myclass& operator=(myclass copy) {
        this->swap(copy);
        return *this;
    }

    ...
};

It's useful in many (but not all) situations. Sometimes you can do better. A vector or a string could have a better assignment which reuses allocated storage if it was large enough.

栖迟 2024-08-13 16:07:22

将公共代码分解为私有成员函数。一个简单的(相当人为的)例子:

#include <iostream>

class Test
{
public:
  Test(const char* n)
  {
    name = new char[20];
    strcpy(name, n);
  }

  ~Test()
  {
    delete[] name;
  }

  // Copy constructor
  Test(const Test& t)
  {
    std::cout << "In copy constructor.\n";
    MakeDeepCopy(t);
  }

  // Assignment operator
  const Test& operator=(const Test& t)
  {
    std::cout << "In assignment operator.\n";
    MakeDeepCopy(t);
  }

  const char* get_name() const { return name; }

private:
  // Common function where the actual copying happens.
  void MakeDeepCopy(const Test& t)
  {        
    strcpy(name, t.name);
  }

private:
  char* name;
};

int
main()
{
  Test t("vijay");
  Test t2(t); // Calls copy constructor.
  Test t3(""); 
  t3 = t2; // Calls the assignment operator.

  std::cout << t.get_name() << ", " << t2.get_name() << ", " << t3.get_name() << '\n';

  return 0;
}

Factor out the common code to a private member function. A simple (rather contrived) example:

#include <iostream>

class Test
{
public:
  Test(const char* n)
  {
    name = new char[20];
    strcpy(name, n);
  }

  ~Test()
  {
    delete[] name;
  }

  // Copy constructor
  Test(const Test& t)
  {
    std::cout << "In copy constructor.\n";
    MakeDeepCopy(t);
  }

  // Assignment operator
  const Test& operator=(const Test& t)
  {
    std::cout << "In assignment operator.\n";
    MakeDeepCopy(t);
  }

  const char* get_name() const { return name; }

private:
  // Common function where the actual copying happens.
  void MakeDeepCopy(const Test& t)
  {        
    strcpy(name, t.name);
  }

private:
  char* name;
};

int
main()
{
  Test t("vijay");
  Test t2(t); // Calls copy constructor.
  Test t3(""); 
  t3 = t2; // Calls the assignment operator.

  std::cout << t.get_name() << ", " << t2.get_name() << ", " << t3.get_name() << '\n';

  return 0;
}
長街聽風 2024-08-13 16:07:22
My &My::operator = (My temp)  // thanks, sellibitze
{
    swap (*this, temp);
    return *this;
}

并实现专门的 std::swap> (我的&,我的&)。

My &My::operator = (My temp)  // thanks, sellibitze
{
    swap (*this, temp);
    return *this;
}

and implement a specialised std::swap<> (My &, My &).

没有伤那来痛 2024-08-13 16:07:22

正如很多发帖者已经指出的那样,让operator=创建一个新的
使用复制构造函数创建对象,然后使用交换是不必在operator=中复制代码的常用技术。

也就是说,我想指出这种技术的一些优点和缺点,以帮助您决定它是否合适。

Pro - 异常安全

如果您的对象有可能导致抛出的资源需求,并且假设交换不会抛出,则此技术提供了异常安全的强有力保证(要么被分配的对象已采用另一个对象的值,要么它是不变)。

缺点 - 资源占用

这种技术的一个问题是它需要在旧对象被释放之前创建一个完整的新对象。如果您的对象需要大量资源,这可能是一个问题。

As has already been pointed out by quite a few posters, having operator= create a new
object with the copy constructor and then use swap is the common technique used to not have to replicate code in operator=.

That said, I want to point out some a pro and a con of this technique to help you decide whether it is appropriate.

Pro - exception safety

If your object has resource requirements that could cause a throw and assuming that swap will not throw, this technique provides the strong guarantee of exception safety (either the object being assigned to has taken on the value of the other object or it is unchanged).

Con - resource footprint

An issue with this technique is that it requires a complete new object to be created before the old one is released. If your object requires a lot of resources, this can be a problem.

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