【发布时间】:2014-07-15 23:40:57
【问题描述】:
这是我遇到的问题的一个最小示例,但我不知道应该如何解决它:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing thing;
app.add_thing(&thing);
}
这编译和运行没有问题,但是,在到达 main 结束时,segfaults 并吐出:
Error in `/path/testapp': free(): invalid pointer: 0x00007fff97118070 ***
任何可能的帮助?我想存储(唯一)指针的原因是 Thing 通常会被派生。
编辑: 一种可行的解决方案:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing* thing = new Thing;
app.add_thing(thing);
}
但据我了解,我应该能够完全避免使用 new 并使用 make_unique?不过,我似乎找不到 make_unique 的实际定义位置。
编辑 2:
这样更合适吗?有没有一种看起来不那么凌乱的方法来做到这一点?否则,它工作得很好。
#include <vector>
#include <memory>
#include <iostream>
class Thing {
public:
int foo = 42;
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(std::unique_ptr<Thing>);
};
void App::add_thing(std::unique_ptr<Thing> thing) {
thingVec.push_back(std::move(thing));
}
int main() {
App app;
app.add_thing(std::unique_ptr<Thing>(new Thing()));
std::cout << app.thingVec.back()->foo << std::endl;
}
因为我可能会得到像
这样的行app.thingVex.back()->barVec.back()->blahMap.emplace("flop", std::unique_ptr<Tree>(new Tree));
【问题讨论】:
-
std::unique_ptr 在对象超出范围时将其销毁。然而,指向的对象已经被销毁,因为它是在堆栈上声明的。
-
他们“忘记”在 C++11 中指定
make_unique。他们在 C++14 中修复了它。在那之前写你自己的make_unique,它是fairly easy。
标签: c++