C++ 将新对象传递给函数c++;

C++ 将新对象传递给函数c++;,c++,C++,我只是想知道这是不是一个坏习惯 for(int i=0;i<1000;i++) happyFunction(new Car()); 这是一个好的做法吗?我应该删除内存分配吗? 我希望我的问题是清楚的。 多谢各位 happyFunction(new Car()); 这本身并不是一个坏习惯(尽管几乎可以肯定是错误的),内存可以在函数中删除。但这会让人困惑,所以这真的不是最好的主意 虽然只有一个参数是安全的,但如果是这样的话 happyFunction(new Car(), new

我只是想知道这是不是一个坏习惯

for(int i=0;i<1000;i++)
    happyFunction(new Car());
这是一个好的做法吗?我应该删除内存分配吗? 我希望我的问题是清楚的。 多谢各位

happyFunction(new Car()); 
这本身并不是一个坏习惯(尽管几乎可以肯定是错误的),内存可以在函数中删除。但这会让人困惑,所以这真的不是最好的主意

虽然只有一个参数是安全的,但如果是这样的话

happyFunction(new Car(), new Thing()); 
其中一条新闻在另一条新消息执行后抛出异常,无法释放内存,因此不安全


<>你总是需要在C++中释放内存,所以第二个例子会导致内存泄漏。有诸如unique_ptr和shared_ptr之类的类可以帮助您管理它,而无需自己编写删除,您可以在网上找到关于它们的任意数量的教程。有两种可能性:

  • happyFunction
    应该拥有指针的所有权,调用者从不担心它。在这种情况下,更明智的做法是写作

    void happyFunction(std::unique_ptr<Car> &&car)
    {
        // car is mine now, and is automatically destroyed when I return
        // unless I explicitly request otherwise
    }
    
    void caller()
    {
        happyFunction(std::unique_ptr<Car>(new Car));
        // the new Car is immediately handed over to the unique_ptr
        // and I don't have to worry about leaks
    }
    

  • 如果您的
    happyFunction()
    返回指向
    new Car()
    创建的内存的指针,则调用者可以保留指向
    new Car()的指针的所有权

    考虑以下代码:

    #include <string>
    #include <iostream>
    
    using std::string;
    using std::cout;
    
    class Car
    {
    public:
        string s;
        Car(string str):s(str) {}
    };
    
    Car* happyFunction(Car *pCar)
    {
        // do something with data pointed to by pCar
        return pCar;
    };
    
    int main()
    {
        // outer pointer to memory allocated by new operator
        Car *pCar = happyFunction(new Car("test"));
        // pCar still points to valid object even after happyFunction() content
        // went out of scope
        cout << pCar->s << "\n";
    
        // release pCar memory outside the happyFunction()
        delete pCar;
    
        return 0;
    }
    
    #包括
    #包括
    使用std::string;
    使用std::cout;
    班车
    {
    公众:
    字符串s;
    Car(stringstr):s(str){}
    };
    汽车*happyFunction(汽车*pCar)
    {
    //对pCar指向的数据执行某些操作
    返回pCar;
    };
    int main()
    {
    //指向新运算符分配的内存的外部指针
    Car*pCar=快乐功能(新车(“测试”);
    //即使在happyFunction()内容之后,pCar仍然指向有效对象
    //超出范围
    
    你最好阅读一些C++的可能的复制品,我想你需要更具体一些。我一般说来是一个很差的练习,但是有时候你可以在不重要的时候方便地做它。真的,真的很难得到这个正确的。例如,如果代码>快乐函数< /C>(或者它调用的函数)抛出异常时,它可能无法
    删除
    汽车
    。因此,这迫使
    happyFunction
    确保它在所有情况下都
    删除
    (必须捕获并重新抛出异常),这使得事情非常糟糕,很容易出错。(即使不使用异常,也很难避免泄漏。请使用智能指针。)除非您以后需要Car对象,否则您应该省略动态分配,只需创建一个静态对象,它将由函数调用临时创建,当函数结束时,它将被删除。我意识到这有点旧,但我想问一下,如果调用方仍然可以保留分配对象的所有权(如果它被调用)如果他使用了
    happyFunction(new Car());
    ,那么打电话的人还能
    删除它吗?我问你是因为你说
    最好在#2中传递一个参考
    ,这意味着另一种方法(可能是原来的方法)存在。在您的示例中,调用方没有指向对象的指针(因为它从不将
    new
    的结果分配给变量,所以它只发送到函数调用)因此,调用方删除对象似乎是不可能的。这似乎是危险的。编译器/ C++标准允许这样做是有原因的,因为它看起来像是永远不应该做的事情?(上面的1节)是您显式传递所有权的方式,这可能是您真正想要做的事情。如果您不想显式传递所有权,而是将其保留在调用方中…只需这样做即可(如上面的示例2所示)。我的意思是使用
    new
    作为函数参数。不过,现在这个问题有点傻,因为我忘了,如果你能控制被调用的代码,你就可以用那种方式处理它。我的想法纯粹是因为你不知道被调用方期望什么/无法控制被调用的函数。谢谢。
    void happyFunction(Car &car)
    {
        // car is still owned by the caller,
        // I just get a reference to use in here
    }
    
    void automatic_caller()
    {
        Car car;
        happyFunction(car);
        // car is always owned by me, and is
        // automatically destroyed at the end of this scope
    }
    
    // alternatively (only if car should live longer than the enclosing scope)
    void dynamic_caller()
    {
        std::unique_ptr<Car> car(new Car);
        // or get pointer from somewhere else ...
        // or get shared_pointer, etc. etc.
        happyFunction(*car);
        // again car is destroyed here unless we do something special
    }
    
    #include <string>
    #include <iostream>
    
    using std::string;
    using std::cout;
    
    class Car
    {
    public:
        string s;
        Car(string str):s(str) {}
    };
    
    Car* happyFunction(Car *pCar)
    {
        // do something with data pointed to by pCar
        return pCar;
    };
    
    int main()
    {
        // outer pointer to memory allocated by new operator
        Car *pCar = happyFunction(new Car("test"));
        // pCar still points to valid object even after happyFunction() content
        // went out of scope
        cout << pCar->s << "\n";
    
        // release pCar memory outside the happyFunction()
        delete pCar;
    
        return 0;
    }