您好
我在班级中有一个* Composant的载体:
class Ordinateur {
string type;
vector<Composant*> Composants;
...
}
我如何编写析构函数?我在StackOverflow上阅读了很多矛盾的答案,所以我有点迷失。
第一版:
virtual ~Ordinateur()
{
for (int i = 0; i < Composants.size(); i++)
{
delete Composants[i];
}
Composants.clear();
}
第二版
virtual ~Ordinateur()
{
Composants.clear();
}
怎么样:
virtual ~Ordinateur()
{
for (int i = 0; i < Composants.size(); i++)
{
delete Composants[i];
}
}
我想避免内存泄漏...
答案 0 :(得分:5)
如果您使用function loadData(props) {
const { fullName } = props;
props.loadRepo(fullName, ['description']);
props.loadStargazers(fullName);
}
class RepoPage extends Component {
constructor(props) {
super(props);
this.renderUser = this.renderUser.bind(this);
this.handleLoadMoreClick = this.handleLoadMoreClick.bind(this);
}
componentWillMount() {
loadData(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.fullName !== this.props.fullName) {
loadData(nextProps);
}
/* ... */
}
分配了Composant
元素,请使用第一个版本,否则第二个版本将泄漏内存。
new Composant();
但是你可以考虑这样做:
virtual ~Ordinateur()
{
for (int i = 0; i < Composants.size(); i++)
{
delete Composants[i]; // this is needed to free the memory
}
// Composants.clear(); // not needed vector cleans itself up
}
然后您根本不需要编写析构函数,元素将删除。并且无需在析构函数中调用class Ordinateur {
std::string type;
std::vector<std::unique_ptr<Composant>> Composants;
...
}
,因为当您的对象被销毁时, vector 将自行完成。
答案 1 :(得分:4)
如果向量拥有它们并且它们指向new
'ed对象,那么您的第一个变体是正确的。
不需要调用vector :: clear()。无论如何,它将由析构函数完成。除了浪费CPU周期之外,它没什么坏处。
你仍然应该使用智能指针,所以你没有这样的问题。
答案 2 :(得分:1)
如果您不使用智能指针,那么第一个解决方案是正确的
答案 3 :(得分:1)
首先,在析构函数中调用clear()
是多余的。
除此之外,还取决于。
粗略地说,你的vector<Composant*> Composants;
可能意味着两件事:
Composants
观察 Composant
在其他地方分配和解除分配的对象。在这种情况下,你的第二个版本是正确的,因为如果你只观察属于别人的东西,那么你不想破坏它。在现代C ++中,这通常是原始指针的唯一好用例。
Composants
自行分配 Composant
个对象(使用new
)。在这种情况下,Componsants
也负责释放,而您的第二个版本基本上正确。但是,在现代C ++中,您通常不直接使用new
和delete
。您改为使用std::unique_ptr
,以便自动处理释放。对于某些用例,也可以使用std::shared_ptr
。
还有第三种可能性。也许根本不需要动态分配Componsant
个对象。也许vector<Componsant>
就足够了,很像vector<int>
或<vector<string>>
就足够了。 C ++初学者倾向于过度使用动态分配(这可能是由于像Java这样的语言的影响,其中自定义类型的实例总是必须使用new
关键字创建。)