Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 复制构造函数和运算符是否必须?_C++_Pointers_Copy Constructor - Fatal编程技术网

C++ 复制构造函数和运算符是否必须?

C++ 复制构造函数和运算符是否必须?,c++,pointers,copy-constructor,C++,Pointers,Copy Constructor,我读到: 具有指针数据成员的每个类都应包括以下成员函数: 破坏者 复制构造函数 运算符=(赋值) 这是真的吗?如果复制对象没有意义怎么办 如果问题中的指针数据成员指向不需要复制或无法更改的内容,该怎么办 我将给出一个具体的例子:一个人出生在某个日期;Date是一个对象,它保存诸如一天的长度或一周中的哪一天之类的值。 我不想“复制”一个人,但即使我不得不这样做,他们不应该指向同一个日期对象吗 如果这是真的,为什么 单词“应该”和“必须”之间有很大的区别。当我阅读你提出的文本时,这意味着我应该强烈地

我读到:

具有指针数据成员的每个类都应包括以下成员函数:

  • 破坏者
  • 复制构造函数
  • 运算符=(赋值)
  • 这是真的吗?如果复制对象没有意义怎么办

    如果问题中的指针数据成员指向不需要复制或无法更改的内容,该怎么办

    我将给出一个具体的例子:一个人出生在某个日期;Date是一个对象,它保存诸如一天的长度或一周中的哪一天之类的值。 我不想“复制”一个人,但即使我不得不这样做,他们不应该指向同一个日期对象吗


    如果这是真的,为什么

    单词“应该”和“必须”之间有很大的区别。当我阅读你提出的文本时,这意味着我应该强烈地考虑做这三件事,而不是绝对必要。逻辑、经验和可行性将在适当的时候和地方压倒指导方针


    也就是说,如果有意义的话,在你的类中有这三样东西总是好的。

    指针数据成员可以表示不同的东西。如果指针只是一个观察指针(指向其他地方管理的对象),那么编译器生成的复制构造函数和运算符(只复制指针的值)绝对没有问题。这里的一个潜在问题是,指针可能比对象寿命长,使其成为悬空指针

    如果它是一个指向堆上分配的并由
    this
    管理的内存的指针,那么您必须确保正确地进行复制。简单地不实现copy(构造函数和操作符)不是一个选项,因为编译器将自动创建它们,而这些很可能不会实现您想要的功能。从2011年开始(使用C++11),您当然可以删除拷贝和/或实现移动(构造函数和操作符)


    但是,最明智的做法是避免使用此类指针,而使用诸如
    std::unique_ptr
    std::vector
    等数据管理类。

    在日期示例中,这实际上不应该是指针。如果是指针,
    如果你得到一份临时文件,或者一份副本,析构函数的作用是什么?呼叫
    删除日期对象上的
    ?如果您两次调用
    delete
    (您现在有2个
    对象),它的未定义行为。

    关于不做什么的示例:

    class Persson
    {
    public:
        Persson( string name, string date )
            : m_name(name)
        {
            m_date = new Date;
            ParseDate( *m_date, date );
        }
        ~Persson()
        {
            delete m_date;
        }
    private:
        string m_name;
        Date* m_date;
    };
    
    如果你曾经复制过一个
    Persson
    ,这会出错。
    复印件很容易,临时的到处都是

    一种可能是指针生命周期由其他人管理,
    在这种情况下,指针可以更多地看作是一个句柄,那么它就没有问题了
    定义复制构造函数、赋值运算符和析构函数

    除非对象的生命周期由其他人管理,否则您应该
    根本不使用指针,直接使用值或智能指针。

    不那么坏的例子:

    class Persson
    {
    public:
        Persson( string name, string date )
            : m_name(name)
        {
            m_date = make_shared<Date>();
            ParseDate( *m_date.get(), date );
        }
    private:
        string m_name;
        shared_ptr<Date> m_date;
    };
    
    总是使用C++的值语义,它是为.bR>所做的。
    看看

    你的例子不清楚。日期对象在哪里分配和删除?如果在构造函数/析构函数中,则会出现严重错误,因为复制的Person对象的析构函数可以删除原始Person对象的Date成员。如果分配/事务发生在类之外,那么就可以了,但它不是典型的C++风格。在对象存在之前,DATE被分配(我有一个数据指针带有日期指针),一个人构造函数包含一个字符串,并且它找到了合适的日期指针。同一个生日的人将共享同一个日期。日期独立。它可以由不同的人使用,在程序开始时分配,在程序结束时删除。这是一个生命周期由其他人管理的对象的示例。您可以使用指针,默认的复制构造函数等将做正确的事情。但是为什么要这样设计
    Date
    ?我看不出std::unique\u ptr或std::vector在这里有什么帮助。也许你的意思是std::shared_ptr需要你努力实现的目标。如果指针指向
    this
    拥有的内存,则
    std::unique\u ptr
    std::vector
    是最好的<代码>std::shared_ptr通常不是类的好成员类型。
    class Persson
    {
    public:
        Persson( string name, string date )
            : m_name(name)
        {
            ParseDate( m_date, date );
        }
    private:
        string m_name;
        Date m_date;
    };