这种在 C++ 中创建局部变量的方法是合法的

bio*_*oan 1 c++ constructor initialization heap-memory stack-memory

我是 C++ 新手,尝试了解如何在 C++ 中创建和使用类。为此,我有以下代码:

class MyClass
{ 
    public:
    MyClass()
    {
        _num = 0;
        _name = "";
    }

    MyClass(MyClass* pMyClass)
    {
        _num = pMyClass->_num;
        _name = pMyClass->_name;
    }

    void PrintValues() { std::cout << _name << ":" << _num << std::endl; }
    void SetValues(int number, std::string name)
    {
        _num = number;
        _name = name;
    }

    private:
    int _num;
    std::string _name;
};


int main()
{
    std::vector<MyClass*> myClassArray;
    MyClass myLocalObject = new MyClass();

    for (int i = 0; i < 3; i++)
    {
        myLocalObject.SetValues(i, "test");
        myClassArray.push_back(new MyClass(myLocalObject));
    }

    myClassArray[1]->PrintValues();
    // use myClassArray further   
}
Run Code Online (Sandbox Code Playgroud)

我从互联网上得到了一个类似的例子并尝试理解它。我的意图是用新的类对象填充 myClassArray。如果我使用 VisualStudio 2022 编译上面的代码,我不会收到任何错误,但我不确定它不会产生内存泄漏,或者是否有更快、更简单的方法。

特别是我不理解以下行: MyClass myLocalObject = new MyClass();

myLocalObject 在堆栈上创建,但使用堆值进行初始化(因为是 new)。如果使用 new 运算符,删除必须在哪里应用?

感谢您的任何建议!

Ben*_*igt 5

您在 处发生内存泄漏MyClass myLocalObject = new MyClass();,因为动态分配的对象用于转换构造新对象myLocalObject(这几乎但不完全是复制构造函数),然后指针丢失。

您也没有显示使用向量的代码,但如果它不删除里面的指针,您将会有更多的内存泄漏。

没有理由有一个几乎复制的构造函数;编译器为您提供了更好的真正的复制构造函数。

更快、更简单的方法是认识到这段代码根本不需要指针。

class MyClass
{ 
    public:
    MyClass()
        : _num(), _name()   // initialize is better than assignment
    {
        //_num = 0;
        //_name = "";
    }

    // compiler provides a copy constructor taking const MyClass&
    //MyClass(MyClass* pMyClass)
    //{
    //    _num = pMyClass->_num;
    //    _name = pMyClass->_name;
    //}

    void PrintValues() { std::cout << _name << ":" << _num << std::endl; }
    void SetValues(int number, std::string name)
    {
        _num = number;
        _name = name;
    }

private:
    int _num;
    std::string _name;
};


int main()
{
    std::vector<MyClass> myClassArray;  // not a pointer
    MyClass myLocalObject; // = new MyClass();   // why copy a default instance when you can just default initialize?

    for (int i = 0; i < 3; i++)
    {
        myLocalObject.SetValues(i, "test");  // works just as before
        myClassArray.push_back(/*new MyClass*/(myLocalObject)); // don't need a pointer, vector knows how to copy objects
        // also, this was using the "real" copy-constructor, not the conversion from pointer
    }

    myClassArray[1].PrintValues(); // instead of ->
    // use myClassArray further   
}
Run Code Online (Sandbox Code Playgroud)

对于需要指针的情况(例如多态性),请使用智能指针:

std::vector<std::unique_ptr<MyClass>> myClassArray;  // smart pointer
myClassArray.push_back(make_unique<MyDerivedClass>(stuff));
Run Code Online (Sandbox Code Playgroud)

std::unique_ptr当对象从向量中删除时,将自动释放该对象(除非您明确将其移出),从而避免需要记住delete.