【问题标题】:default constructors and object copying默认构造函数和对象复制
【发布时间】:2011-02-21 03:23:57
【问题描述】:

我想知道为什么在这种情况下我需要声明一个默认构造函数。一方面,如果我将其排除在外,编译器不会自动执行此操作吗?无论如何,我仍然不明白为什么它是必要的。此外,即使我省略 'obj_B = origin.obj_B;' 也会出现错误

class B
{
public:
    bool theArray[5] ;

    B(bool x) {theArray[1] = x;};
    //B(){};    
};

class A
{
public:
    B obj_B;

    A() : obj_B(1) {};
    A(A const &origin) {obj_B = origin.obj_B;}; //error:no matching function for call 
                                                      //to B::B()
}; 

int main () 
{
    std::vector <A> someAs;
    for(int q=0;q<10;q++)
        someAs.push_back(A());

    for(int q=0;q<10;q++)
        std::cout << someAs[q].obj_B.theArray[1] << std::endl;
}

【问题讨论】:

    标签: c++ constructor assignment-operator copying


    【解决方案1】:

    如果您不指定备用构造函数,编译器只会创建默认构造函数。

    因为你做了:

    B(bool x) {theArray[1] = x;}
    

    不会为您创建默认构造函数。

    您遇到的具体错误是因为 A(A const &origin) 没有明确指定用于 obj_B 的构造函数。

    下面的代码可以工作:

    A(A const &origin) : obj_B(1) {obj_B = origin.obj_B;}
    

    顺便说一句,函数定义不需要尾随分号。

    【讨论】:

    • @Wheatevo 酷。我知道这在这段代码中不是问题,但是是否有任何理由使用默认的复制构造函数或默认的赋值运算符可能无法复制非动态分配的数组(例如 theArray5)的内容?
    • 在绝大多数情况下,如果不使用动态分配的内存,默认的复制构造函数、默认的赋值运算符和默认的析构函数就足够了。
    • 无论如何,默认的复制或赋值运算符没有理由无法复制典型数组的内容。如果您正在处理动态分配的内存或类似引用计数器的东西,您只需要制作自己的复制构造函数。默认副本会自动将一个对象的每个成员变量复制到另一个对象(不包括静态成员)。
    • @Wheatevo 好的。这就是大家一直在说的。但这就是我一直遇到的问题,我一生都无法弄清楚出了什么问题。那么极少数情况呢?
    • 我建议用您遇到问题的代码发布一个新问题 :)
    【解决方案2】:

    如果您没有为类定义 任何 ctor,编译器将合成一个默认构造函数。如果你定义了另一个构造函数(例如,一个带参数的构造函数),那么编译器会为你合成一个,你必须自己定义一个。

    如果您关心,C++ 0x 添加了一个“=default;”声明告诉编译器提供一个默认情况下会提供的 ctor,即使您已经定义了另一个 ctor。

    【讨论】:

      【解决方案3】:

      要为A 定义不需要B 的默认构造函数的复制构造函数,请使用成员初始化语法:

      class A {
      public:
          A(A const& origin) : obj_B(origin.obj_B) {}
          //...
      };
      

      【讨论】:

        【解决方案4】:

        最后一点...

        假设您没有定义非默认构造函数,未能定义默认构造函数将导致 theArray[] 的元素未定义。这是一个坏习惯,通常会导致错误。

        【讨论】:

          猜你喜欢
          • 2020-05-14
          • 2014-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-16
          • 1970-01-01
          • 1970-01-01
          • 2018-03-09
          相关资源
          最近更新 更多