【问题标题】:Copy-constructor, assignment operator, new复制构造函数,赋值运算符,new
【发布时间】:2019-07-08 19:20:17
【问题描述】:

我对复制构造函数和赋值运算符有一些疑问。我知道当我定义一个构造函数时,编译器不会合成默认构造函数。我怀疑是否可以只定义复制构造函数。我会说不,因为如果我定义了复制构造函数,则默认构造函数不会被合成,所以我无法初始化对象,因为我需要该类的对象,而我没有。我不知道这是否正确。我的第二个疑问是关于包含指针的类的类似值的实现。到目前为止,我看到的每个代码都在复制和赋值运算符中使用了 new 运算符。例如:

#include <string>
#include <vector>
#include "book.hh"

class Student
{
    std::string name;
    unsigned int id;
    unsigned int age;
    char gender;
    std::vector<Book> * books;

 /*Copy-constructor*/
    Student (const Student & other)
    {
        name = other.name;
        id = other.id;
        age = other.age;
        gender = other.gender;
        books = new std::vector<Book> (*other.books);
    }

 /*Assignment operator*/
    Student & operator = (const Student & other)
    {
        if (this != &other)
        {
            name = other.name;
            id = other.id;
            age = other.age;
            gender = other.gender;
            delete books;
            books = new std::vector<book> (*other.books);
        }
        return *this;
    }
 }

文档说应该实现一个构造函数。构造函数呢?在这种情况下,如何在没有构造函数(不是复制构造函数)的情况下实例化一个类? Morover,我不明白为什么它在复制构造函数和赋值运算符中使用 new 。例如,我会在赋值运算符正文中执行 *books = *(other.books);这也是正确的吗?

【问题讨论】:

  • books 需要一个内存插槽才能使*books = *(other.books); 工作。因此,您需要为向量分配内存。当然使用动态分配的向量是有问题的,但我不确定你的问题在这里
  • ...但既然你有一个vector 来持有Books - new 似乎是个坏主意。
  • 为什么是向量指针?
  • 执行:std::vector&lt;Book&gt; books; 并在复制 ctor 和复制赋值运算符中:books = other.books;
  • std::vector&lt;Book&gt; * books;改成std::vector&lt;Book&gt; books;,你就不需要定义任何特殊的成员函数了。

标签: c++ copy-constructor assignment-operator


【解决方案1】:

查看The Rule of Three,它指出您通常应该定义一个复制构造函数、一个赋值运算符和一个析构函数(如果需要)。如果您有理由定义其中之一,那么您几乎肯定有理由定义其他内容。您正在管理动态内存,这意味着您可能应该在构造函数中对其进行初始化。

你的复制和赋值操作符必须做new std::vector&lt;Book&gt; (*other.books);,因为如果他们只复制指针,比如books = other.books;,你最终会得到两个Students共享同一个Books,这(通常)是一个配方为灾难。

(旁注:copy-and-swap idiom 可以省去一些麻烦。)

最后,确保您的析构函数deletes 分配了任何内存。正如@Ted Lyngmo 所指出的,在这种特定情况下,使用普通的std::vector 而不是指向一个的指针将消除定义任何特殊成员函数的需要。

【讨论】:

  • 三法则是关于复制 ctor、赋值操作和析构函数 - 与默认 ctor 无关。事实上,大多数类可能不会提供默认的 cto - OP 的类可能不应该提供一个。
  • 更好的旁注:首先没有理由 newstd::vector&lt;Book&gt;
  • *books = *other.books是“将other.books指向的位置的内容分配给books指向的位置”。这会让你陷入一个受伤的世界,因为books 指向什么?没有什么!它尚未由默认构造函数初始化。你不能分配给你不拥有的内存。
  • @Peanojr 未指向有效对象的指针几乎是无用的(一个例外是作为图中的哨兵)。它不必指向动态分配的对象,但替代方案在这里并不是特别吸引人。自动分配将超出范围并留下pointer dangling。指向全局 books 是不好的(每个人都指向同一件事),从免费 books 列表中拉出 books 会冒着用完免费 books 的风险。最好的解决方案是这里根本不使用指针。
  • 指针的默认初始化是不确定的垃圾,所以是的,仍然存在分配给该位置的问题。它必须指向有效的std::vector,然后才能分配任何内容。
猜你喜欢
  • 1970-01-01
  • 2017-01-14
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 2013-04-13
  • 2014-10-12
相关资源
最近更新 更多