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释放错误。还要关注析构顺序的问题

上一篇下一篇

猜你喜欢

热点阅读