unique_ptr到对象数组,构造函数有不同的行为

时间:2014-12-05 07:30:50

标签: c++ c++11 unique-ptr

我在g ++ 4.4.6中使用--std = c ++ 0x:

编译了以下c ++测试
#include <iostream>
#include <memory>
using namespace std ;

class Arrs
{
private :
    int i ;
public:
    Arrs(int i_=0):i(i_){ cout << "cons" << endl ; }
    void setinArr(int i_){i = i_ ; }
    ~Arrs(){ cout << "(" << i << ")" << endl ; }
};

class MM
{
private:
    int icnt ;
    unique_ptr<Arrs[]> ptr ;
public:
    MM(int i_):icnt(i_){ ptr.reset( new Arrs[i_] ); }
    void setinMM(int i_,int j_){
        //ptr[i_] = j_ ;
        ptr[i_].setinArr(j_)  ;
    }
    ~MM(){}
};

int main(int argc, char ** argv) {
    MM m(5) ;
    for(int i=0;i<5;i++)
        m.setinMM(i,50+i) ;
}

我的问题是:如果我在setinMM中编码:ptr [i _] .setinArr(j_),输出将为:

cons
cons
cons
cons
cons
(54)
(53)
(52)
(51)
(50)

如果我改为编码ptr [i_] = j_,则输出为:

cons
cons
cons
cons
cons
cons
(50)
cons
(51)
cons
(52)
cons
(53)
cons
(54)
(54)
(53)
(52)
(51)
(50)

我不知道ptr [i_] = j_发生了什么;在MM.setinMM中导致此输出, 任何提示?!

1 个答案:

答案 0 :(得分:3)

由于您没有为operator=作业重载int,因此以下声明:

ptr[i_] = j_ ;

使用隐式定义的 copy-assignment-operator

Arrs& Arrs::operator=(const Arrs&)

通过以Arrs作为参数的复制初始化创建j_的临时实例,并将该临时实例传递给运算符。创建临时文件是附加打印件的来源。

通过替换:{/ p>,可以通过将单个参数调用的构造函数声明为explicit来避免此类错误。

Arrs(int i_ = 0) : i(i_) {}

将两个声明如下:

Arrs() : Arrs(0) {}  // make sure default constructor is not explicit
explicit Arrs(int i_) : i(i_) {} // make explicit this one

或(如果不支持委托构造函数):

Arrs() : i(0) {}
explicit Arrs(int i_) : i(i_) {}