unique_ptr для массива объектов, конструктор имеет другое поведение

0

У меня есть следующий c++ тест, скомпилированный в g++ 4.4.6 с --std = c++ 0x:

#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) ;
}

мой вопрос: если я код: ptr [i_]. setinArr (j_) в setinMM будет:

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 вызывают этот вывод, любой намек?!

  • 2
    Это не имеет ничего общего с unique_ptrs.
Теги:
c++11
unique-ptr

1 ответ

3
Лучший ответ

Так как вы не перегружаете operator= для назначения int, то следующий оператор:

ptr[i_] = j_ ;

использует неявно определенный оператор копирования-присваивания:

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

создав временный экземпляр Arrs через инициализацию копирования с помощью j_ в качестве аргумента и передав это временное значение в оператор. Создание временного - это когда появляются дополнительные отпечатки.

Такие ошибки можно было бы избежать, объявив конструкторы, вызываемые одним аргументом как 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_) {}
  • 0
    Спасибо, мой env - c ++ 0x, а не в c ++ 11, согласно stackoverflow.com/questions/11391108/… , вызов другого конструктора напрямую не поддерживается в C ++ 0x, ваш код очень помогает, мой путаница ушла !!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню