У меня есть следующий 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 вызывают этот вывод, любой намек?!
Так как вы не перегружаете 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_) {}