我有C方面的背景知识,正在尝试着手研究C ++类,以及在对象离开作用域时如何调用析构函数。附带说明一下,鉴于我要尝试执行的操作的性质,我宁愿不使用std :: array <>或std :: vector <>之类的STL结构作为下面提供的数据容器。
这是我的理解的高级概述。给定一些课程:
class some_class{
public:
int * member;
size_t n_members;
some_class(size_t count) ...
~some_class() ...
// a member function or operator overload
// that returns an instance of some_class
some_class do_something()
}
...
some_class * container;
// Some scope
{
some_class foo = some_class();
some_class * bar = new some_class();
container[0] = bar;
}
当some_class foo
离开范围时,其析构函数将被调用。如果我想将指向实例的指针存储some_class
到container
作用域之外,则需要some_class bar
在堆上实例化,以使内存不会在离开作用域时立即被取消分配,就像在C语言中一样。
现在,目的some_class
是保存任意数量的数据,因此int * member
需要在堆上进行分配。
上面给出了some_class()的构造函数和析构函数如下所示:
// some_class constructor
some_class::some_class(size_t count) : n_members(count){
member = new int[count];
}
// some_class destructor
some_class::~some_class(){
delete[] member;
}
现在我的问题变得很明显:如果我需要添加some_class
从do_something()
方法返回的实例,则可以保证会出现内存错误(在这种情况下为double-free),因为它do_something()
返回的是堆栈分配的some_class
:
some_class * container = new some_class[n];
// Some scope
{
some_class foo = some_class();
some_class bar = foo.do_something();
container[0] = &bar; // <-- I know this is stupid but that's the point of this question
}
delete[] container;
我的解决方法是使foo.do_something()
返回指向的实例的指针some_class
。当然,不是解决方案。如何以真正的C ++方式正确解决这种情况?
例如,我一直在阅读的一件事是使用共享指针或唯一指针(或通常的智能指针)。但是,我的理解是,使用这些指针需要您实例化堆中的对象。这也确实对解决要求foo.do_something()
返回指针的整个问题没有帮助。
无论如何,任何想法都将不胜感激。
智能指针可用于将指针保存在some_class内,如下所示:
#include <memory>
class some_class{
public:
// smart pointer instead of raw pointer
std::unique_ptr<int[]> member;
size_t n_members;
some_class(size_t count = 0) : member(new int[count]), n_members(count) {}
// destructor not needed
// a member function or operator overload
// that returns an instance of some_class
some_class do_something();
};
int main()
{
int n = 3;
// smart pointer instead of raw pointer
std::unique_ptr<some_class[]> container(new some_class[n]);
{
some_class foo = some_class(10);
some_class bar = foo.do_something();
// use std::move to transfer pointer ownership
container[0] = std::move(bar);
}
// no need to delete
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句