【问题标题】:trivial assignment琐碎的任务
【发布时间】:2013-09-10 05:05:17
【问题描述】:

在试图理解this answer 时,似乎new can be classified as a "copy constructor"delete sometimes as a "trivial destructor"

我可以找到next to nothing (that I can quickly grasp) on "trivial assignment",但如果它是隐式声明的,如果它的类没有虚拟成员函数或虚拟基类,如果它的直接基类和嵌入对象是“琐碎有一个简单的赋值运算符”。

我找到了a question on yahoo about implicit declaration,但令我惊讶的是,它没有回答。

读了virtual member functions之后,我的大脑很疼。

此外,我是一个猴子看猴子做的程序员,所以我要得到这个的唯一方法就是看到它的实际效果。请使用第一个答案中提供的示例解释上述“琐碎”的定义,std::string 使用newdelete 或出于不太明显的原因有一个琐碎的赋值运算符。

【问题讨论】:

    标签: c++ declaration assignment-operator member-functions


    【解决方案1】:

    New 可以使用复制构造函数,而 delete 使用析构函数。复制构造函数或析构函数可能是微不足道的。

    话虽如此,您很有可能不需要担心构造函数/析构函数是否很长一段时间都是微不足道的。

    new 调用构造函数来构造对象。如果T 类型的构造函数的一个参数是T 的一个实例,它是一个复制构造函数:您正试图从另一个对象构造一个对象的实例

    class Foo
    {
        public:
            Foo(int x) // not a copy constructor
            : mX(x)
            { }
    
            Foo(const Foo& inOther) // copy constructor
            : mX(inOther.mX)
            { }
        private:
            int mX;
    };
    
    class Bar
    {
        public:
            Bar(int x)
            : mX(x)
            { }
    
            // no copy constructor specified.. C++ will build an implicit one for you
        private:
            int mX;
    } 
    };
    
    Foo a(1);  // uses the first constructor (not a copy)
    Foo b(a); // uses a copy constructor
    Foo c = a; // copy constructor
    
    Foo* d = new Foo(1); // construct a new instance of Foo (not a copy)
    Foo* e = new Foo(a); // copy
    
    Bar f(1); // normal constructor
    Bar g(f); // IMPLICIT copy constructor
    

    如果你的类没有像 Bar 这样的复制构造函数,C++ 通常会为你提供一个(除非你有 explicit 构造函数或使用 C++11 关键字删除复制构造函数,否则总是会为你提供一个)。这个复制构造函数非常简单:它复制类的每个成员。

    一个普通的复制构造函数是特殊的。仅当编译器为您隐式创建复制构造函数时,才能创建普通的复制构造函数,并且:

    • 您班级的所有成员都可以轻松复制
    • 您没有任何虚拟方法或虚拟基类
    • 您的所有基类都可以轻松复制。

    如果你在你的类中指定了一个构造函数,根据定义,它不是微不足道的。 Foo 没有简单的复制构造函数,因为它是用户定义的。 Bar 有一个隐式复制构造函数,因为它不是用户定义的。隐式复制构造函数很简单,因为复制 mX 很简单(复制 int 很简单)。

    类似的规则也适用于析构函数。一个普通的析构函数遵循相同的规则,并删除

    它对你有什么帮助?该规范列出了一些关于普通构造函数/析构函数的关键行为。特别是,如果你有一个微不足道的构造函数和析构函数,否则你可以做的事情是非法的。然而,它们都非常细微,对于 99.9% 的 C++ 代码开发来说并不重要。它们都处理您可以不构造或破坏对象而侥幸逃脱的情况。

    例如,如果我有一个工会:

    union MyUnion {
        int x;
        ClassA y;
        ClassB z;
    }
    

    如果 y 和 z 有微不足道的构造函数和析构函数,C+ 将为我编写该联合的复制构造函数。如果其中一个具有重要的构造函数/析构函数,我必须自己为联合编写复制构造函数。

    您可以做的另一件事是快速销毁数组。通常,当您删除一个数组时,您必须确保在每个项目上调用析构函数。如果你能证明每个元素的析构函数是微不足道的,那么你可以跳过销毁元素,而只是释放内存。 std::vector 在后台执行此操作(因此您不必这样做)

    【讨论】:

    • 很棒的答案!我不想问,但是琐碎的赋值运算符是从哪里来的?'
    • 这些方法相同。如果我有一个对象Bar f(1) and Bar g(2),写f = g 会调用赋值运算符。由于Bar 缺少一个,编译器提供了一个隐式赋值运算符。因为它的所有成员都有一个平凡的赋值运算符,所以 Bar 的隐式赋值运算符是平凡的。我还添加了另一件“棘手”的事情,你可以在 0.1% 的代码中做这件事,它关心微不足道的析构函数,释放内存
    • 泰!我想我现在理解了隐式声明。除此之外,“微不足道”仅仅是该条件的标识,并且当前对象或其类“路径”中绝对没有虚函数和类(对不起,主要的 C++ 菜鸟)?
    • 是的,它只是一个与满足这些要求的类上的隐式构造函数关联的名称。
    猜你喜欢
    • 2011-12-15
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多