Smartpointer в С++

Опубликовано Sep 30, 2011 в ООП | 5 коммент.

, , ,

  1. Напишите класс С++, реализующий “умный” указатель.
  2. Напишите класс С++, реализующий любой “умный” указатель.
  3. Более конкретно, напишите класс С++, реализующий  владеющий “умный” указатель.

Если задача формулируется по первому варианту, то годится любая из классических реализаций, и вопросы могут и не задаваться. Тем не менее, вопрос, в смысле “…чего тебе надобно, старче? “, заданный в комментариях к посту очень уместен. Он и побудил к уточнениям условия (появились варианты 2 и 3) и добавлению всяких других сведений.

Для начинающего программиста допустимы ошибки в реализации, которые должны быть исправлены после указания на них. Программист с опытом, должен написать код, в котором ничего не упущено и отсутствуют принципиальные ошибки.

Возможен еще такой вариант. Дается, например, задача про владеющий указатель. При обсуждении желательно услышать, что это – auto_ptr из STL Дальше для экономии времени и некоторой помощи начинающему программисту может быть предложен код, содержащий заголовки методов стандартного класса, но без их реализации. То есть что-то подобное следующему

template struct auto_ptr_ref {
	Y* y_pointer;
    auto_ptr_ref (Y* p){}
};
 
template class auto_ptr {
private:
	X* x_pointer;
public:
 
	//ctor
	explicit auto_ptr(X* p = 0) throw(){};
 
	//copy ctors
	auto_ptr(auto_ptr& p) throw(){};
 
	template auto_ptr(auto_ptr& p) throw(){};
 
	//assignment operators
	auto_ptr& operator = (auto_ptr& p) throw(){};
 
	template auto_ptr& operator=(auto_ptr& p) throw(){};
 
	//dtor
	~auto_ptr() throw(){};
 
	//release
	X* release() throw(){};
 
	//re-initialization
	void reset(X* p = 0) throw(){};
 
	//access by pointer
	X* get() const throw() {};
 
	X& operator*() const throw(){};
 
	X* operator->() const throw(){};
 
	//type and other special conversions
	auto_ptr(auto_ptr_ref p) throw(){};
 
	template operator auto_ptr_ref() throw(){};
 
	auto_ptr& operator = (auto_ptr_ref p) throw(){};
 
	template operator auto_ptr() throw(){};
};

Нужно будет написать код этих методов и придумать, как продемонстрировать, что создан именно “умный”  указатель. Другими словами требуется предложить и реализовать тестовые вызовы, которые демонстрируют выполнение стандартного поведения класса std::auto_ptr.

auto_ptr: возможная реализация (подсказка)

template struct auto_ptr_ref {
	Y* y_pointer;
    auto_ptr_ref (Y* p) : y_pointer(p) {
    }
};
 
template class auto_ptr
{
private: X* x_pointer;
public:
 
	//ctor
	explicit auto_ptr(X* p = 0) throw() : x_pointer(p){
	};
 
	//copy ctors
	auto_ptr(auto_ptr& p) throw() : x_pointer(p.release()){
	};
 
	template auto_ptr(auto_ptr& p) throw(): x_pointer(p.release()){
	};
 
	//assignment operators
	auto_ptr& operator = (auto_ptr& p) throw(){
		reset(p.release());
        return *this;
	};
 
	template auto_ptr& operator=(auto_ptr& p) throw(){
		reset(p.release());
        return *this;
	};
 
	//dtor
	~auto_ptr() throw(){
		delete x_pointer;
	};
 
	//release
	X* release() throw(){
		X* tmp(x_pointer);
        x_pointer = 0;
        return tmp;
	};
	//re-initialization
	void reset(X* p = 0) throw(){
		 if (x_pointer != p) {
          delete x_pointer;
          x_pointer = p;
		 }
	};
 
	//access by pointer
	X* get() const throw() {
		return x_pointer;
	};
 
	X& operator*() const throw(){
		return *x_pointer;
	};
 
	X* operator->() const throw(){
		return x_pointer;
	};
 
	//type and other special conversions
	auto_ptr(auto_ptr_ref p) throw() : x_pointer(p.y_pointer){
	};
 
	template operator auto_ptr_ref() throw(){
		return auto_ptr_ref(release());
	};
 
	auto_ptr& operator = (auto_ptr_ref p) throw(){
		reset(p.y_pointer);
        return *this;
	};
 
	template operator auto_ptr() throw(){
		return auto_ptr(release());
	};
 
};