Я написал свой собственный класс auto_ptr
, но обнаружил некоторую магию.
C++ Заголовочный файл
class A {
private:
int data;
public:
A(int data);
void print() const;
};
class auto_ptr_ref;
class auto_ptr {
private:
A* ptr = 0;
public:
auto_ptr(A* p);
auto_ptr(auto_ptr& p);
auto_ptr(auto_ptr_ref p);
~auto_ptr();
auto_ptr& operator =(auto_ptr& p);
void release();
operator auto_ptr_ref();
A& operator*() const;
A* operator->() const;
};
class auto_ptr_ref {
private:
auto_ptr* ptr;
public:
auto_ptr* get();
auto_ptr_ref(auto_ptr* ptr);
};
C++ Исходный файл
A::A(int data) : data(data) {}
void A::print() const {
printf("%d\n", data);
}
auto_ptr::auto_ptr(A* p) : ptr(p) {}
auto_ptr::auto_ptr(auto_ptr& p) {
ptr = p.ptr;
p.release();
}
auto_ptr::auto_ptr(auto_ptr_ref p) {
*this = *(p.get());
p.get()->release();
}
auto_ptr::~auto_ptr() {
delete ptr;
}
void auto_ptr::release() {
ptr = NULL;
}
auto_ptr::operator auto_ptr_ref() {
return auto_ptr_ref(this);
}
auto_ptr& auto_ptr::operator =(auto_ptr& p) {
if (ptr != NULL)
delete ptr;
ptr = p.ptr;
p.release();
return *this;
}
A& auto_ptr::operator*() const {
return (*ptr);
}
A* auto_ptr::operator->() const {
return ptr;
}
auto_ptr_ref::auto_ptr_ref(auto_ptr* ptr) : ptr(ptr) {}
auto_ptr* auto_ptr_ref::get() {
return ptr;
}
Тест 1
int main() {
auto_ptr ptr(auto_ptr(new A(10)));
ptr->print();
return 0;
}
Компиляция и печать кода 10
.
Тест 2
int main() {
A* data = new A(10);
auto_ptr ptr(auto_ptr(data));
ptr->print();
return 0;
}
Код не компилируется.
error: запрос для члена 'print in' ptr, который имеет тип non-class 'auto_ptr (auto_ptr)
Тест 3
int main() {
A* data = new A(10);
auto_ptr ptr((auto_ptr(data)));
ptr->print();
return 0;
}
И этот код компилирует и печатает 10
!
Не могли бы вы объяснить, что происходит во втором тестовом случае? Почему "ptr" имеет тип auto_ptr (auto_ptr)?
Заявление
auto_ptr ptr(auto_ptr(data));
Объявляет функцию с именем "ptr", которая имеет параметр с именем "data" типа "auto_ptr" и возвращает значение типа "auto_ptr".
Итак, не делайте эту ошибку)
auto_ptr
? C ++ отказался от этого (за то, что он был опасным и неинтуитивным взломом компрометации дизайна), в тот момент, когда они могли указать что-то лучше (unique_ptr
).