在c ++中,将一个动态分配的对象传递给一个函数(总是)一个坏主意?

con*_*ist 3 c++ pointers function

我知道问题的标题看起来有点令人头疼,但我真的不知道怎么用一句话来问这个问题.我只会告诉你我的意思:

void f(T *obj)
{
    // bla bla
}
void main()
{
    f(new T());
}
Run Code Online (Sandbox Code Playgroud)

据我所知,(几乎)每个新的都需要一个删除,这需要一个指针(由new返回).在这种情况下,new返回的指针不存储在任何地方.这会是内存泄漏吗?

C++是否有某种神奇的功能(程序员看不见),它会在函数结束后删除对象,或者这种做法总是一个坏主意?

Ale*_*kov 7

没有特别的魔力,也不会自动调用删除.

绝对不是"总是一个坏主意" - 如果函数以某种形式获取对象的所有权,那么调用这样的函数是完全有效的方法:

container.AddAndTakeOwnership(new MyItem(42));
Run Code Online (Sandbox Code Playgroud)


eca*_*mur 5

是的,这总是一个坏主意; 功能和构造应该明确他们的所有权的语义,如果他们希望采取或共享传递指针他们应该接受的所有权std::unique_ptrstd::shared_ptr分别.

有许多遗留API采用所有权语义的原始指针,即使在标准库中(例如locale构造函数Facet *具有所有权),但任何新代码都应该避免这种情况.

即使构建一个unique_ptr或者shared_ptr你可以避免使用new关键字,在后一种情况下使用make_shared和在前一种情况下编写一个make_unique功能模板,该模板应该很快就会添加到该语言中.


Pio*_*ycz 5

在这种情况下,new 返回的指针不会存储在任何地方。那么这会是内存泄漏吗?

不,这不一定是内存泄漏。该指针作为参数存储到f

void f(T *obj)
//        ^^^  here pointer is "stored"
{
    // bla bla
    delete obj; // no memory leak if delete will be called on obj
}
void main()
{
    f(new T());
  //  ^^^^^^^  this "value" will be stored as an argument to f
}
Run Code Online (Sandbox Code Playgroud)

C++ 是否有某种魔力(程序员看不到)在函数结束后删除对象,或者这种做法总是一个坏主意?

你的例子中没有魔法。正如我所展示的 - 必须显式调用删除。

更好的是使用智能指针,然后 C++“魔法”起作用,并且不需要删除。

void f(std::unique_ptr<T> obj)
{
    // bla bla
}
void main()
{
    f(new T());
}
Run Code Online (Sandbox Code Playgroud)