4
다음은 C++ 11 연구용 예제를 구현 한 것입니다. 모든 생성자와 소멸자가 콘솔로 출력하도록했습니다. 그러나 놀랍게도 두 번 호출되지만 생성자는 세 번 호출됩니다.왜 파괴자에 의해 생성 된 두 객체가 세 번 호출되는지
예기치 않은 것 같습니다. 0x7fff5fbff6d0입니다. 이 객체가 생성되면? 하지만 생성자 호출이 연관되지 않은 이유는 무엇입니까?
왜 이런 일이 발생하고 있습니까?
template<typename T>
class ArrayWrapper{
public:
ArrayWrapper():data_(nullptr), size_(0){
cout << "Default ctor called "<< this <<endl;
}
ArrayWrapper(size_t n, const T& val) : data_(new T[n]), size_(n){
cout << "ctor_n_val called "<< this << endl;
for_each(data_, data_+size_, [&](T& elem){ elem=val; });
}
ArrayWrapper(const ArrayWrapper& other): data_(new T[other.size_]), size_(other.size_)
{
cout << "copy ctor called "<< this <<endl;
copy(other.data_, other.data_+other.size_, data_);
}
ArrayWrapper(ArrayWrapper&& other): data_(other.data_), size_(other.size_)
{
cout << "move ctor called"<<endl;
other.data_ = nullptr;
other.size_ = 0;
}
ArrayWrapper<T>& operator=(const ArrayWrapper& other){
cout << "copy assignment called" <<endl;
if(this != &other){
delete data_;
data_ = new T[other.size_];
copy(other.begin(), other.end(), begin());
size_ = other.size_;
}
return *this;
}
ArrayWrapper<T> operator=(ArrayWrapper&& other){
cout << "move assignment called " <<this << " <- " <<&other <<endl;
swap(size_, other.size_);
swap(data_, other.data_);
}
~ArrayWrapper(){
cout <<"Destroying " << this << " Size " << size_ <<endl;
}
typedef T* iterator;
typedef const T* const_iterator;
T* begin() {
return data_;
}
T* end(){
return data_ + size_;
}
const T* begin() const {
return data_;
}
const T* end() const {
return data_ + size_;
}
const T* cbegin() const {
return data_;
}
const T* cend() const {
return data_ + size_;
}
size_t size(){
return size_;
}
public:
T* data_;
size_t size_;
};
template<typename T>
ArrayWrapper<T> make_array(size_t n, const T& val){
cout <<"Factory method called"<<endl;
return ArrayWrapper<T>(n, val);
}
template<typename T>
std::ostream& operator<<(std::ostream& os, const ArrayWrapper<T>& arr){
for(const T& elem: arr){ os << elem << ", ";}
return os;
}
int main(){
size_t n = 10;
ArrayWrapper<int> a4(n, 1);
a4 = make_array(n, 4); // move assignment:
cout << "A4: " << a4 << endl;
}
출력 :
ArrayWrapper<T>& operator=(ArrayWrapper&& other)
// ^
당신이 값으로 반환이 있지만 return
문이 없기 때문에, 당신이있어 :
$ g++-mp-4.8 -std=c++11 move.cpp
$ ./a.out
ctor_n_val called 0x7fff5fbff6b0
Factory method called
ctor_n_val called 0x7fff5fbff6e0
move assignment called 0x7fff5fbff6b0 <- 0x7fff5fbff6e0
Destroying 0x7fff5fbff6d0 Size 0
Destroying 0x7fff5fbff6e0 Size 10
A4: 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
Destroying 0x7fff5fbff6b0 Size 10
+1 반환 유형이 고정되고'return * this;'가 추가되면 생성자 호출은 2 개와 일치하는 소멸자 호출이 2 개 있습니다. – Praetorian
나는 그것을 시험해 보았다. – xiaochuanQ
이동 할당 연산자가 'other.size_ = 0;'을 설정하려고합니다. –