删除函数内的对象:丑陋,容易出错,效率低下,通常不是异常安全的

Han*_*Goc 0 c++ memory virtual-destructor

根据以下文章:为什么在范围结束时调用析构函数?

使用new创建对象然后在同一范围的末尾删除它的代码是丑陋的,容易出错,效率低下,并且通常不是异常安全的.例如:

 void very_bad_func()    // ugly, error-prone, and inefficient
    {
        X* p = new X;
        // use p
        delete p;  // not exception-safe
    }
Run Code Online (Sandbox Code Playgroud)

我希望我的代码不丑:

我正在创建一个类型的对象,TiXmlDocument并在函数的末尾删除它.

void DataLoader::readXmlFile(const string & file)
{
    TiXmlDocument *doc = new TiXmlDocument(file.c_str());
    bool loadOkay = doc->LoadFile();
    TiXmlHandle hdl(doc);

    //work is done in here
    if(loadOkay)
    {
        TiXmlElement * pRoot = hdl.FirstChildElement().Element();//.FirstChildElement().Element();
        parseFile(pRoot);
    }
    else
    {
        cout <<"Error: "<< doc->ErrorDesc()<<endl;
    }
    //deallocate doc
    delete doc;
}
Run Code Online (Sandbox Code Playgroud)

问题(S):

  • DataLoader::~DataLoader() {}在离开函数范围后,我应该使用析构函数来确保删除对象吗?无需明确删除它delete doc.

建议我做了以下事情:

TiXmlDocument doc(xmlFile.c_str());
bool loadOkay = doc.LoadFile();
TiXmlHandle hdl(&doc);
Run Code Online (Sandbox Code Playgroud)

我开始认为使用动态内存就像java和c#在c ++中不是一个好的做法(应该以负责任的方式使用).如果没有真正的原因可以使用它,那就不要.如果处理不当,将导致内存泄漏,难以追踪.


Nei*_*irk 7

创建没有new的对象:

void func()
{
    X p;
    // use p
}
Run Code Online (Sandbox Code Playgroud)

或者如果你必须使用new(例如,它是一个大对象),那么使用智能指针:

void func()
{
    std::unique_ptr<X> p(new X);
    // use p
}
Run Code Online (Sandbox Code Playgroud)

问题解决了!