一个示例auto_ptr实现 [英] A Sample auto_ptr implementation
问题描述
大家好,
我正在构建一个使用自定义auto_ptr
实现的示例应用程序。
程序崩溃时出现以下输出: -
输出(Debug Assertion失败)
----------
发布名为
复制构造函数
aap:ptr2 = 10
aap:ptr3 = 20
aap: ptr3 = 10
aap:退出应用
删除指针...... 10
删除指针......- 572662307(...有问题吗? )
代码
--------
#include< iostream>
使用命名空间std;
// MyAutoPtr接口
模板< class T>
class MyAutoPtr
{
public:
显式MyAutoPtr(T * ptr = 0);
~MyAutoPtr();
模板< class U>
MyAutoPtr(MyAutoPtr< U * rhs);
//复制构造函数成员模板,初始化此成员指针
与任何其他兼容的auto_ptr
模板<类U>
MyAutoPtr(MyAutoPtr< U>& rhs);
//赋值运算符
模板< class U>
MyAutoPtr< T>& operator =(MyAutoPtr< U>&rhs);
//放弃所有权
T * release();
T * get()const;
//重置auto_ptr,删除指针,假设所有权p
void reset(T * ptr = 0);
T& operator *()const;
T * operator->()const;
private:
T * pointee;
//模板< class U>
//朋友类MyAutoPtr< U> ;;
};
//实施
模板< typename T>
inline MyAutoPtr< T> :: MyAutoPtr(T * ptr):pointee(ptr )
{}
模板< class T>
inline MyAutoPtr< T> ::〜MyAutoPtr()
{
if(pointee)
{
cout<<" \ n\t删除指针..."<< * pointee;
删除指针;
}
}
模板<类T>
模板<类U>
内联MyAutoPtr< T> :: MyAutoPtr(MyAutoPtr< U>& rhs):
pointee(rhs.release())
{
cout<<" \ n\t copy constructor" ;;
}
模板< class T>
模板&l t; U类>
MyAutoPtr< T>& MyAutoPtr< T> :: operator =(MyAutoPtr< U>& rhs)
{
cout<<" \ n\ t inside operator =" ;;
if(this!=& rhs)
{
cout<<" \ n\t Inside运营商=,调用重置" ;;
重置(rhs.release());
}
返回* this;
}
模板< class T>
T * MyAutoPtr< T> :: get()const
{
返回指针;
}
模板< class T>
inline T& MyAutoPtr< T> :: operator *()const
{
return * pointee;
}
模板< class T>
inline T * MyAutoPtr< T> :: operator->()const
{return pointee; }
模板< class T>
T * MyAutoPtr< T> :: release()
{
cout<<" \ n\t release被称为;
T * oldp = pointee;
pointee = 0;
返回oldp;
}
模板< class T>
void MyAutoPtr< T> ::重置(T * p)
{
cout<<" \ n\t reset称为;
if (pointee!= p)
{
删除指针;
// pointee = 0;
}
pointee = p;
}
void main()
{
MyAutoPtr< intintp(new int(10));
MyAutoPtr< intintp2(intp);
MyAutoPtr< intintp3(new int(20) );
// cout<<"" ptr1 ="<< * intp;
cout<<" \ n \t aap:ptr2 ="<< * intp2;
cout<<" \ n\ aap:ptr3 ="<< * intp3;
intp3 = intp2; //
============================== 1
cout<<" \ n\ aap:ptr3 ="<< * intp3;
cout<<" \ nn \\ t aap:exiting app" ;;
}
看来,在调试时,该类的自定义运算符=不知何故
在1处被调用,因此在破坏时出现问题。 (因为删除
在同一个指针上被调用两次)
---------------------- -------------------------------------------------- ---------------------------------
Q1。上述代码有问题吗?
Q2。什么导致operator =不被调用以及如何修复它?
Q3。以下语句(在类接口中)导致编译器
错误,如果没有注释掉
private:
T * pointee;
//模板< class U>
//朋友类MyAutoPtr< U> ;;
MSDN将此错误定义为: : -
编译器错误C3772
错误消息
" name" :无效的朋友模板声明
声明类模板专业化的朋友是无效的。
您不能声明类的显式或部分特化
模板并在同一语句中声明了该朋友的专家化。名称占位符标识无效的
声明。
更正此错误
- 不要声明类模板专业化的朋友。 />
- 如果适合您的应用程序,请声明该类的朋友
模板,或声明特定部分或明确
专业化的朋友。
为什么会出现这样的错误,如果这不是专业化的话?或者是某种方式的专业化?
--------------------------- -------------------------------------------------- ----------------------------
任何帮助都将受到高度赞赏!
谢谢!
尝试定义不带模板U参数的赋值运算符:
//赋值运算符
MyAutoPtr< T>& operator =(MyAutoPtr< T>& rhs);
为什么你还需要那个U,释放应该返回指针
被传递给重置,所以T和U应该相等。
Ankur Arora写道:
大家好,
我正在构建一个使用自定义auto_ptr
实现的示例应用程序。
程序崩溃时输出如下: -
输出(Debug Assertion failed)
----------
发布名为
复制构造函数
aap:ptr2 = 10
aap:ptr3 = 20
aap:ptr3 = 10
aap:退出应用
删除指针... 10
删除指针......- 572662307(.. .problem?)
代码
--------
数据点:你的公司de为我工作输出
发布名为
复制构造函数
aap:ptr2 = 10
aap:ptr3 = 20
内部运营商=
内部运营商=,呼叫重置
发布名为
重置叫a / b
aap:ptr3 = 10
aap:退出应用
删除指针... 10
所以我只有尼特:
#include< iostream>
using namespace std;
在标题中使用命名空间std是个坏主意。
[snip]
template< class T>
inline MyAutoPtr< T> ::〜MyAutoPtr()
{
if(pointee)
{
cout<<" \ n\t正在删除指针......"<< * pointee ;
删除指针;
}
}
删除将执行其在这种情况下,它必须是
中的空值。
[snip]
模板< class T>
模板< class U>
MyAutoPtr< T>& MyAutoPtr< T> :: operator =(MyAutoPtr< U>& rhs)
{
cout<<" \ n\ t inside operator =" ;;
if(this!=& rhs)
当T和U不同时,这个if子句不会编译。
你可以使用
if(this-> pointee == rhs.pointee)
(我认为)。
{
cout<<" \ n\ t inside operator =,call reset" ;;
重置(rhs.release());
}
返回* this;
}
[snip]
void main()
[snip]
Main返回int。此时我得到了一个关于g ++的错误。
看来,在调试时,该类的自定义运算符=在某种程度上不是
在1处被调用,因此在破坏时出现问题。 (因为删除
在同一个指针上被调用两次)
---------------------- -------------------------------------------------- ---------------------------------
Q1。上述代码有什么问题吗?
它适用于g ++。
Q2。是什么导致operator =不被调用以及如何修复它?
编译器中的错误?
[snip]
Best
Kai-Uwe Bux
Yakov Gerlovin写道:
尝试定义无模板的赋值运算符U参数:
//赋值运算符
MyAutoPtr< T>& operator =(MyAutoPtr< T>& rhs);
为什么你还需要那个U,释放应该返回指针
传递给重置,所以T和U应该相等。
他需要它来支持多态性。当D来自B时,MyAutoPtr< B>
应该是可构造的并且可以从MyAutoPtr< D>分配。
但OP可以定义复制构造函数和分配运营商分别来自T
。对于复制构造函数,我记得这是必需的。我是
不确定作业运营商是否需要它。
最好
Kai-Uwe Bux
Hi All,
I''m building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-
Output (Debug Assertion failed)
----------
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
Deleting pointee...-572662307 (...problem ?)
Code
--------
#include<iostream>
using namespace std;
// MyAutoPtr Interface
template <class T>
class MyAutoPtr
{
public:
explicit MyAutoPtr(T* ptr=0);
~MyAutoPtr();
template <class U>
MyAutoPtr(MyAutoPtr<U*rhs);
//copy constructor member template, initialize this member pointer
with any other compatible auto_ptr
template <class U>
MyAutoPtr(MyAutoPtr<U>& rhs);
//assignment operator
template <class U>
MyAutoPtr<T>& operator=(MyAutoPtr<U>& rhs);
//relinquish ownership
T* release();
T* get() const;
//reset the auto_ptr, delete pointee, assume ownership of p
void reset(T* ptr=0);
T& operator*() const;
T* operator->() const;
private:
T* pointee;
//template <class U>
//friend class MyAutoPtr<U>;
};
//Implementation
template<typename T>
inline MyAutoPtr<T>::MyAutoPtr(T* ptr):pointee(ptr)
{ }
template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}
template <class T>
template <class U>
inline MyAutoPtr<T>::MyAutoPtr(MyAutoPtr<U>& rhs) :
pointee(rhs.release())
{
cout<<"\n\t copy constructor";
}
template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
cout<<"\n\t Inside operator=";
if(this!=&rhs)
{
cout<<"\n\t Inside operator=, calling reset";
reset(rhs.release());
}
return *this;
}
template <class T>
T* MyAutoPtr<T>::get() const
{
return pointee;
}
template <class T>
inline T& MyAutoPtr<T>::operator *() const
{
return *pointee;
}
template<class T>
inline T* MyAutoPtr<T>::operator->() const
{ return pointee; }
template<class T>
T* MyAutoPtr<T>::release()
{
cout<<"\n\t release called";
T* oldp=pointee;
pointee=0;
return oldp;
}
template<class T>
void MyAutoPtr<T>::reset(T* p)
{
cout<<"\n\t reset called";
if(pointee!=p)
{
delete pointee;
//pointee=0;
}
pointee=p;
}
void main()
{
MyAutoPtr<intintp(new int(10));
MyAutoPtr<intintp2(intp);
MyAutoPtr<intintp3(new int(20));
//cout<<"ptr1= "<<*intp;
cout<<"\n\t aap: ptr2= "<<*intp2;
cout<<"\n\t aap: ptr3= "<<*intp3;
intp3 = intp2; //
============================== 1
cout<<"\n\t aap: ptr3= "<<*intp3;
cout<<"\n\t aap: exiting app";
}
It seems, on debugging, that class''s custom operator= is somehow not
been called at 1 and hence a problem while destructing. (since delete
is being called twice on the same pointer)
---------------------------------------------------------------------------------------------------------
Q1. Any problems with the above code ?
Q2. What is causing operator= not to be called and how to fix it ?
Q3. Following statements (in the class interface) cause compiler
errors, if not commented out
private:
T* pointee;
//template <class U>
//friend class MyAutoPtr<U>;
MSDN defines this error as:-
Compiler Error C3772
Error Message
"name" : invalid friend template declaration
It is invalid to declare a friend of a class template specialization.
You cannot declare an explicit or partial specialization of a class
template and in the same statement declare a friend of that
specialization. The name placeholder identifies the invalid
declaration.
To correct this error
-Do not declare a friend of a class template specialization.
-If appropriate for your application, declare a friend of the class
template, or declare a friend of a particular partial or explicit
specialization.
Why such error, if this is not a specialization? or is it a
specialization somehow?
---------------------------------------------------------------------------------------------------------
Any help will be highly appreciated!
Thanks!
Try to define assignment operator without template U parameter:
//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);
Why do you need that ''U'' anyway, release should return the pointer to
be passed to reset, so T and U should be equal.
Ankur Arora wrote:
Hi All,
I''m building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-
Output (Debug Assertion failed)
----------
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
Deleting pointee...-572662307 (...problem ?)
Code
--------Just a data point: your code works for me with output
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
Inside operator=
Inside operator=, calling reset
release called
reset called
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
So I just have nits:
#include<iostream>
using namespace std;It''s a bad idea to use using namespace std in a header.
[snip]template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}delete will perform its own check for 0. It is required to be a null-op in
that case.
[snip]template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
cout<<"\n\t Inside operator=";
if(this!=&rhs)This if-clause will not compile when T and U are different.
You could use
if ( this->pointee == rhs.pointee )
instead (I think).
{
cout<<"\n\t Inside operator=, calling reset";
reset(rhs.release());
}
return *this;
}[snip]
void main()[snip]
Main returns int. I get an error with g++ at this point.
It seems, on debugging, that class''s custom operator= is somehow not
been called at 1 and hence a problem while destructing. (since delete
is being called twice on the same pointer)
---------------------------------------------------------------------------------------------------------
Q1. Any problems with the above code ?It works with g++.
Q2. What is causing operator= not to be called and how to fix it ?A bug in your compiler?
[snip]
Best
Kai-Uwe Bux
Yakov Gerlovin wrote:
Try to define assignment operator without template U parameter:
//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);
Why do you need that ''U'' anyway, release should return the pointer to
be passed to reset, so T and U should be equal.He needs it to support polymorphism. When D is derived from B, MyAutoPtr<B>
should be constructible and assignable from MyAutoPtr<D>.
But the OP could define copy-constructor and assignment operator from T
separately. For the copy-constructor, I recall that this is needed. I am
not sure if it is needed for the assignment operator.
Best
Kai-Uwe Bux
这篇关于一个示例auto_ptr实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!