首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除函数中的对象:丑陋、易出错、效率低下,而且通常不例外安全。

删除函数中的对象:丑陋、易出错、效率低下,而且通常不例外安全。
EN

Stack Overflow用户
提问于 2015-03-23 12:57:24
回答 2查看 92关注 0票数 0

根据以下文章:为什么在作用域结束时没有调用析构函数?

使用new创建对象,然后在相同范围的末尾删除对象的代码很难看,容易出错,效率低下,而且通常不例外安全。例如:

代码语言:javascript
复制
 void very_bad_func()    // ugly, error-prone, and inefficient
    {
        X* p = new X;
        // use p
        delete p;  // not exception-safe
    }

我希望我的准则不是丑陋的:

我正在创建一个TiXmlDocument类型的对象,并在函数结束时删除它。

代码语言:javascript
复制
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;
}

问题:

  • 我是否应该使用DataLoader::~DataLoader() {}析构函数,以确保在离开函数的作用域后删除该对象?不需要显式删除它,delete doc

按照建议,我做了以下工作:

代码语言:javascript
复制
TiXmlDocument doc(xmlFile.c_str());
bool loadOkay = doc.LoadFile();
TiXmlHandle hdl(&doc);

我开始认为,像java和c#一样使用动态内存在c++中不是一个好的实践(应该以负责任的方式使用)。如果没有真正的原因使用它,那么就不使用它。如果处理不正确,它将导致内存泄漏,这是很难跟踪的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-23 13:01:48

要么创建您的对象而没有新的:

代码语言:javascript
复制
void func()
{
    X p;
    // use p
}

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

代码语言:javascript
复制
void func()
{
    std::unique_ptr<X> p(new X);
    // use p
}

问题解决了!

票数 7
EN

Stack Overflow用户

发布于 2015-03-23 13:05:00

这仍然是丑陋的(在我看来),当然容易出错,效率低下,而且不例外安全。如果在此函数期间抛出异常,则不会发生delete,并且会泄漏内存。

在这种情况下,根本不需要new;使用一个自动变量,它将在函数退出时自动销毁,无论是通过到达结束、返回还是抛出。

代码语言:javascript
复制
TiXmlDocument doc(file.c_str());

如果出于某种原因需要动态分配,那么使用智能指针或其他雷伊类型来获得相同的自动行为:

代码语言:javascript
复制
auto doc = std::make_unique<TiXmlDocument>(file.c_str());            // C++14 or later
std::unique_ptr<TiXmlDocument> doc(new TiXmlDocument(file.c_str())); // C++11

要回答最后一个问题:使用析构函数来释放由类实例管理的资源,而不是函数调用中使用的临时资源。同样,通常应该使用RAII类型作为成员变量来自动管理这些资源,这样就不需要自己编写析构函数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29210834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档