一个示例auto_ptr实现 [英] A Sample auto_ptr implementation

查看:48
本文介绍了一个示例auto_ptr实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我正在构建一个使用自定义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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆