Example:
Class *_obj1;
Class *_obj2;
void doThis(Class *obj) {}
void create() {
Class *obj1 = new Class();
Class obj2;
doThis(obj1);
doThis(&obj2);
_obj1 = obj1;
_obj2 = &obj2;
}
int main (int argc, const char * argv[]) {
create();
_obj1->doSomething();
_obj2->doSomething();
return 0;
}
这将创建 2 个对象,创建指向它们的指针,然后 main() 对每个对象调用一个方法。 Class 对象创建一个 char* 并存储 C 字符串“Hello!”在里面; ~Class() 释放器释放内存。 doSomething() 方法使用 printf() 打印出“buff: %s”。够简单的。现在,如果我们运行它,我们会得到:
Dealloc
巴夫:您好!
浅黄色: ́_ˇ
显然是栈对象在这里不起作用- 很明显,当函数退出时,指针 _obj2 指向堆栈中的某个位置。这就是为什么我在上一个问题中使用堆对象,人们告诉我这是“愚蠢的”。
所以,第一个问题是:如果如何将堆栈对象 (obj2) 转换为堆对象,以便在 create() 退出后不会释放它?我想要一个直接的答案,而不是像很多人那样傲慢地回答“你做错了”。因为在这种情况下堆栈对象无法工作,所以堆对象似乎是唯一的方法。编辑:此外,转换回堆栈对象也很有用。
第二个问题:堆对象“错误”的具体例子是创建一个新的vector<string>*
使用new
操作员。如果动态分配STL对象是错误的,那么正确的方法是什么?显然,如果您将它们创建为堆栈对象,则会失败,因为它们会立即被释放,但我被告知(再次,由一位非常高级的成员)动态分配它们可能会损坏堆。那么正确的做法是什么呢?
所以,第一个问题是:如何将堆栈对象(obj2)转换为堆对象,以便在 create() 退出后它不会被释放?我想要一个直接的答案
直接的答案是:您无法在堆栈和堆之间“转换”对象。正如其他人指出的那样,您可以创建存在于另一个空间中的对象的副本,但仅此而已。
第二个问题:堆对象“错误”的具体示例是使用 new 运算符创建一个新的向量*。如果动态分配STL对象是错误的,那么正确的方法是什么?显然,如果您将它们创建为堆栈对象,则会失败,因为它们会立即被释放,但我被告知(再次,由一位非常高级的成员)动态分配它们可能会损坏堆。
动态分配 STL 对象本身不会损坏堆。 (不知道您可能在哪里听说过。)
如果您想在创建它的函数之外使用堆栈分配的 STL 对象,你不能,因为对象所在的堆栈空间仅在创建它的函数内有效。
但是,您可以返回该对象的副本:
std::vector<char> SomeFunc()
{
std::vector<char> myvector;
// myvector.operations ...
return myvector;
}
不过,正如我所说,这将返回对象的副本,而不是原始对象本身 - 这是不可能的,因为包含该对象的堆栈在函数返回后被展开。
另一种选择是让调用者传递指向函数操作的对象的引用/指针(如果这对您的特定场景有意义):
void SomeFunc(std::vector<char>& destination)
{
// destination.operations ...
}
void AnotherFunc()
{
std::vector<char> myvector;
SomeFunc(myvector);
}
正如您所看到的,您仍然分配了堆栈上的所有内容,并且避免了依赖复制构造函数返回对象副本的(有时是间接的)开销。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)