我有foo一个包含std :: auto_ptr成员的类,我想复制构造,但这似乎不允许.作业有类似的东西.请参阅以下示例:
struct foo
{
private:
int _a;
std::string _b;
std::auto_ptr< bar > _c;
public:
foo(const foo& rhs)
: _a(rhs._a)
, _b(rhs._b)
, _c(rhs._c)
// error: Cannot mutate rhs._c to give up ownership - D'Oh!
{
}
foo& operator=(const foo& rhs)
{
_a = rhs._a;
_b = rhs._b;
_c = rhs._c;
// error: Same problem again.
}
};
Run Code Online (Sandbox Code Playgroud)
我可以声明_c,mutable但我不确定这是否正确.有没有人有更好的解决方案?
编辑
好吧,我没有得到我期待的那种答案,所以我会对这个问题有所了解.
foo在堆栈上创建,并通过值传递到容器类(而不是stl),然后超出范围.我对容器代码没有任何控制权.(它实际上是一个活动的队列实现,有bug.)bar班是一个相当重量级的解析器.它的性能非常差new,delete因此即使它是可复制的,也会太昂贵.bar …我听说自动指针拥有自己的对象,而共享指针可以有许多指向它们的对象.为什么我们不一直使用共享指针.
与此相关的是智能指针,人们可以将这个术语与共享指针互换使用.它们是一样的吗?
该网站声明" 所有权,来源和汇 ":
"当你复制一个auto_ptr,你自动将所有权从源转移auto_ptr到目标auto_ptr; 如果目标auto_ptr已经拥有一个对象,那么该对象首先被释放.在复制之后,只有目标auto_ptr拥有指针并在适当的时候删除它,而源被设置回null状态,不能再用于引用拥有的对象."
现在考虑的定义operator=()为templacte<classX> class auto_ptr,在Stroustrup的第14章,368页的C++编程语言第三版:
auto_ptr& operator=(auto_ptr& a) throw() { ptr = a.ptr; a.ptr = 0; }
我无法看到操作员释放所解决的对象ptr,万一ptr != 0!
为什么这个代码并不会导致内存泄漏?
int iterCount = 1000;
int sizeBig = 100000;
for (int i = 0; i < iterCount; i++)
{
std::auto_ptr<char> buffer(new char[sizeBig]);
}
Run Code Online (Sandbox Code Playgroud)
WinXP sp2,编译器:BCB.05.03
请考虑以下代码:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
struct A
{
int a;
A(int a_):a(a_) {}
};
int main()
{
vector<auto_ptr<A> > as;
for (int i = 0; i < 10; i++)
{
auto_ptr<A> a(new A(i));
as.push_back(a);
}
for (vector<auto_ptr<A> >::iterator it = as.begin(); it != as.end(); ++it)
cout << (*it)->a << endl;
}
Run Code Online (Sandbox Code Playgroud)
在尝试编译它时,我从g ++中得到以下模糊的编译器错误:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/proba.d" -MT"src/proba.d" -o"src/proba.o" "../src/proba.cpp"
/usr/include/c++/4.1.2/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp …Run Code Online (Sandbox Code Playgroud) std::auto_ptr不允许存储在STL容器中,例如std::vector.但是,偶尔会出现需要返回多态对象集合的情况,因此我无法返回对象向量(由于切片问题).我可以使用std::tr1::shared_ptr并坚持使用vector,但是我必须付出高昂的代价来维护单独的引用计数,并且拥有实际内存(容器)的对象不再在逻辑上"拥有"对象,因为它们可以被复制出来它不考虑所有权.
C++ 0x以这种形式为这个问题提供了一个完美的解决方案std::vector<std::unique_ptr<t>>,但是我无法访问C++ 0x.
其他一些说明:
boost::ptr_container容器(即boost::ptr_vector),但我想避免这种情况,因为它打破了调试器(内部存储在void *s中,这意味着很难在调试器中查看实际存储在容器内的对象)我在Exception类中遇到auto_ptr问题,我最终简化为:
#include <memory>
class MyException
{
std::auto_ptr<int> m_foo2;
};
int main()
{
try
{
throw MyException();
}
catch (const MyException&)
{
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这无法编译:
/perforce/unstable/test/Common/Exceptions/TestException4.cpp:在函数'int main()'中:/perforce/unstable/test/Common/Exceptions/TestException4.cpp:12:错误:没有匹配函数来调用' MyException :: MyException(MyException)'/ perforce/unstable/test/Common/Exceptions/TestException4.cpp:4:note:候选者是:MyException :: MyException()/ perforce/unstable/test/Common/Exceptions/TestException4.cpp :4:注意:MyException :: MyException(MyException&)/ perforce/unstable/test/Common/Exceptions/TestException4.cpp:12:error:in thrown expression
如果我删除auto_ptr,错误就会消失.
这是因为正在复制或分配例外吗?有没有auto_ptr在异常中使用s 的方法?
我需要在我的代码中从shared_ptr获取auto_ptr.我可以做反向操作 - 将auto_ptr转换为shared_ptr,因为shared_ptr有这样的构造函数:
template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
Run Code Online (Sandbox Code Playgroud)
我可以将shared_ptr转换为auto_ptr吗?或者设计不可能?
假设我已经分配了堆A*,我希望将其作为参数传递给boost::bind.
boost::bind保存以供稍后处理某些STL的容器boost::functions.
我想确保A*在销毁STL容器时销毁.
示范:
A* pA = new A();
// some time later
container.push_back(boost::bind(&SomeClass::HandleA, this, pA);
// some time later
container is destroyed => pA is destroyed too
Run Code Online (Sandbox Code Playgroud)
怎么做到呢?
编辑
也许我想要的不是那么现实.
我有原始指针和函数接收原始指针.通过boost :: bind延迟调用.此时我想要自动内存管理,以防boost :: bind想要执行.我很懒,所以我想使用"准备好"的智能指针解决方案.
std :: auto_ptr看起来像个好人,但是......
auto_ptr<A> pAutoA(pA);
container.push_back(boost::bind(&SomeClass::HandleA, this, pAutoA);
Run Code Online (Sandbox Code Playgroud)
不编译(见这里)
auto_ptr<A> pAutoA(pA);
container.push_back(boost::bind(&SomeClass::HandleA, this, boost::ref(pAutoA));
Run Code Online (Sandbox Code Playgroud)
pAutoA被破坏,删除了底层的pA.
编辑02
在上面提到的容器中,我将需要使用不同的参数存储misc"回调".其中一些是对象的原始指针.由于代码是旧的,我并不总是可以改变它.
编写自己的包装器来存储容器中的回调是最后的手段(可能是唯一的),因此是赏金.
auto-ptr ×10
c++ ×10
shared-ptr ×2
boost-bind ×1
c++03 ×1
collections ×1
exception ×1
g++ ×1
memory-leaks ×1
stl ×1
vector ×1