假设我有类似
的多态类结构class Base
{
//some implementation
};
class Deriv: public Base
{
//implementation
}
class Case1
{
boost::scoped_ptr<A> a_ //polymorphic data member owned by C
public:
Case1(A* a):a_(a)
{
}
};
class Case2
{
boost::scoped_ptr<A> a_ //polymorphic data member owned by C
public:
Case2(std::auto_ptr<A> a):a_( a.release() )
{
}
};
我有一个第三类case1 / 2,它拥有上述多态对象之一。现在我需要将指向Base / Deriv对象的指针传递给case1 / 2类的构造函数,该构造函数接受此对象的所有权。我应该将此对象作为智能指针传递,例如auto_ptr说清楚我正在关注这个对象,或允许原始指针(案例1)允许更简单的语法,如
Case1 c(new Deriv);
//compared to
Case2 c(std::auto_ptr<Base>(new Deriv));
答案 0 :(得分:3)
你需要传递一个智能指针,你需要命名该智能指针(例如,它不能是一个临时指针):
std::auto_ptr<Base> p(new Deriv);
Case2 c(p); // this constructor would need to take the `auto_ptr` by reference
// so that it can steal ownership.
在您的第一个示例Case1 c(new Deriv);
中,如果在执行new Deriv
和Case1
对象在其构造函数中获取它的所有权之间抛出异常,则该对象可能会泄露。
在第二个示例中,如果没有为智能指针命名,则在某些情况下可能会泄漏对象。值得注意的是,这可能发生if you have more than one argument to a function。
答案 1 :(得分:0)
如果你的类完全拥有传递给它的对象,那么你最好通过在所有适用的情况下使用auto_ptr来明确这一点。必须明确构造auto_ptr是最好的情况,因为它强制API用户知道你拥有该对象并减少了所有权混淆的可能性。
如果你的类具有可变所有权,那么通常,它的方式是提供原始指针和销毁函数。
class best_practices {
std::function<void(A*)> destructor;
A* ptr;
public:
best_practices(A* a, std::function<void(A*)> destructfunc)
: ptr(a), destructor(destructfunc) {}
~best_practices() {
destructor(ptr);
}
};
答案 2 :(得分:0)
我没有这个最佳实践的来源,但总的来说,如果您要以某种方式存储资源,我发现最好以相同的方式获取该资源。
原因是在C ++ 0x中,复制/移动是在给出参数时完成的,然后你只需将它移动到存储器中,例如:
struct store_string
{
store_string(std::string s) : // potentially free, copy if not
s(std::move(s)) // free
{}
std::string s;
};
或者在C ++ 03中,如果您的类型可以廉价地默认构建:
struct store_string
{
store_string(std::string ss) // make necessary copy
{
s.swap(ss); // free
}
std::string s;
};
所以对你来说,我会这样做:
class Case2
{
boost::scoped_ptr<A> a_ //polymorphic data member owned by C
public:
Case2(boost::scoped_ptr<A>& aa)
{
a.swap(aa); // take resource
}
};
这使您的工作变得简单,并让客户知道如何管理资源。