Che*_*Alf 55 c++ unique-ptr delete-operator c++11
根据N3290 std::unique_ptr
在其构造函数中接受一个删除参数.
但是,我不能在Windows中使用Visual C++ 10.0或MinGW g ++ 4.4.1,也不能在Ubuntu中使用g ++ 4.6.1.
因此,我担心我对它的理解是不完整或错误的,我不能看到显然被忽略的删除论证的观点,那么任何人都可以提供一个有效的例子吗?
我最好还想看看它是如何工作的unique_ptr<Base> p = unique_ptr<Derived>( new Derived )
.
可能会使用标准中的一些措辞来备份示例,即使用您正在使用的任何编译器,它实际上做了它应该做的事情?
Ben*_*ley 45
这适用于MSVC10
int x = 5;
auto del = [](int * p) { std::cout << "Deleting x, value is : " << *p; };
std::unique_ptr<int, decltype(del)> px(&x, del);
Run Code Online (Sandbox Code Playgroud)
在gcc 4.5上,这里
我会跳过标准,除非你不认为这个例子完全符合你的期望.
Phi*_*tte 25
为了补充所有以前的答案,有一种方法可以有一个自定义删除器,而不必通过在其中使用函数指针或类似的东西来"污染"unique_ptr签名,如下所示:
std::unique_ptr< MyType, myTypeDeleter > // not pretty
Run Code Online (Sandbox Code Playgroud)
这可以通过为std :: default_delete模板类提供特化来实现,如下所示:
namespace std
{
template<>
class default_delete< MyType >
{
public:
void operator()(MyType *ptr)
{
delete ptr;
}
};
}
Run Code Online (Sandbox Code Playgroud)
现在所有std::unique_ptr< MyType >
"看到"这个专业化的东西都将被删除.请注意,它可能不是您想要的所有内容std::unique_ptr< MyType >
,因此请仔细选择您的解决方案.
Che*_*Alf 11
我的问题已经得到了很好的回答.
但是,万一人们想知道,我错误地认为a unique_ptr<Derived>
可以移动到a unique_ptr<Base>
然后会记住Derived
对象的删除,即Base
不需要虚拟析构函数.那是错的.我选择Kerrek SB的评论作为"答案",除了评论不能做到这一点.
@Howard:下面的代码说明了实现我认为动态分配删除器的成本必须意味着unique_ptr
支持开箱即用的一种方法:
#include <iostream>
#include <memory> // std::unique_ptr
#include <functional> // function
#include <utility> // move
#include <string>
using namespace std;
class Base
{
public:
Base() { cout << "Base:<init>" << endl; }
~Base() { cout << "Base::<destroy>" << endl; }
virtual string message() const { return "Message from Base!"; }
};
class Derived
: public Base
{
public:
Derived() { cout << "Derived::<init>" << endl; }
~Derived() { cout << "Derived::<destroy>" << endl; }
virtual string message() const { return "Message from Derived!"; }
};
class BoundDeleter
{
private:
typedef void (*DeleteFunc)( void* p );
DeleteFunc deleteFunc_;
void* pObject_;
template< class Type >
static void deleteFuncImpl( void* p )
{
delete static_cast< Type* >( p );
}
public:
template< class Type >
BoundDeleter( Type* pObject )
: deleteFunc_( &deleteFuncImpl< Type > )
, pObject_( pObject )
{}
BoundDeleter( BoundDeleter&& other )
: deleteFunc_( move( other.deleteFunc_ ) )
, pObject_( move( other.pObject_ ) )
{}
void operator() (void*) const
{
deleteFunc_( pObject_ );
}
};
template< class Type >
class SafeCleanupUniquePtr
: protected unique_ptr< Type, BoundDeleter >
{
public:
typedef unique_ptr< Type, BoundDeleter > Base;
using Base::operator->;
using Base::operator*;
template< class ActualType >
SafeCleanupUniquePtr( ActualType* p )
: Base( p, BoundDeleter( p ) )
{}
template< class Other >
SafeCleanupUniquePtr( SafeCleanupUniquePtr< Other >&& other )
: Base( move( other ) )
{}
};
int main()
{
SafeCleanupUniquePtr< Base > p( new Derived );
cout << p->message() << endl;
}
Run Code Online (Sandbox Code Playgroud)
干杯,
这有效.破坏恰当.
class Base
{
public:
Base() { std::cout << "Base::Base\n"; }
virtual ~Base() { std::cout << "Base::~Base\n"; }
};
class Derived : public Base
{
public:
Derived() { std::cout << "Derived::Derived\n"; }
virtual ~Derived() { std::cout << "Derived::~Derived\n"; }
};
void Delete(const Base* bp)
{
delete bp;
}
int main()
{
std::unique_ptr<Base, void(*)(const Base*)> ptr = std::unique_ptr<Derived, void(*)(const Base*)>(new Derived(), Delete);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
39885 次 |
最近记录: |