unique_ptr解惑
2019-07-31 本文已影响0人
413x
通过这个例子,我意识到编写代码验证,是学习一门语言的最好方法。
结论:
若一个类中有一个私有成员std::unique_ptr,当该实例被析构时,若该类的析构函数为虚函数,即使析构函数中未编写对unique_ptr指向对象进行析构的代码,编译器会在该类析构时调用相关unique_ptr指向对象的析构函数,若析构函数不是虚函数,则会导致new-delete释放错误。
#include <iostream>
#include <bits/unique_ptr.h>
class KeyFetcher {
public:
virtual ~KeyFetcher(){
std::cout << "KeyFetacher destruct" << std::endl;
}
};
class LicenseFetcher {
public:
virtual ~LicenseFetcher(){
std::cout << "LicenseFetcher destruct" << std::endl;
}
};
class ClearKeyLicenseFetcher : public LicenseFetcher{
public:
virtual ~ClearKeyLicenseFetcher(){
std::cout << "ClearKeyLicenseFetcher destruct" << std::endl;
}
};
class ClearKeyFetcher : public KeyFetcher{
public:
ClearKeyFetcher(
std::unique_ptr<LicenseFetcher> license_fetcher) :
license_fetcher_(std::move(license_fetcher)){}
virtual ~ClearKeyFetcher(){
std::cout << "ClearKeyFetcher destruct" << std::endl;
}
private:
std::unique_ptr<LicenseFetcher> license_fetcher_;
};
class ClearKeyCasPlugin{
private:
std::unique_ptr<KeyFetcher> mKeyFetcher;
public:
virtual ~ClearKeyCasPlugin(){
}
void test(){
std::unique_ptr<ClearKeyLicenseFetcher> license_fetcher;
license_fetcher.reset(new ClearKeyLicenseFetcher());
std::unique_ptr<ClearKeyFetcher> key_fetcher;
key_fetcher.reset(new ClearKeyFetcher(std::move(license_fetcher)));
mKeyFetcher = std::move(key_fetcher);
}
};
int main() {
ClearKeyCasPlugin* p=new ClearKeyCasPlugin();
for(int i=0;i<2;i++){
p->test();
std::cout << "----------------------------" << std::endl;
}
delete(p);
return 0;
}
上述是我怀疑存在内存泄露的代码改编而成,通过asan检测不存在内存泄漏,总结如下:
若一个类中有一个私有成员std::unique_ptr,当该实例被析构时,若该类的析构函数为虚函数,即使析构函数中未编写对unique_ptr指向对象进行析构的代码,编译器会在该类析构时调用相关unique_ptr指向对象的析构函数,若析构函数不是虚函数,则会导致new-delete释放错误。还要关注析构顺序的问题