这种在 C++ 中创建局部变量的方法是合法的
It is legal this approach for create a local variable in C++
我是 C++ 的新手,尝试了解如何在 C++ 中创建和使用 class。
为此,我有以下代码:
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
}
从网上找了一个类似的例子,试着理解一下。
我的意图是用新的 class 对象填充 myClassArray。
如果我使用 VisualStudio 2022 编译上面的代码,我不会出错,但我不确定它不会产生内存泄漏,或者是否有更快更简单的方法。
尤其是下面这行我不明白:
MyClass myLocalObject = new MyClass();
myLocalObject是在栈上创建的,但是是用堆值初始化的(因为是new的)。如果使用 new 运算符, delete 必须应用在哪里?
感谢您的任何建议!
您在 MyClass myLocalObject = new MyClass();
处发生内存泄漏,因为 dynamically-allocated 对象用于 converting-construct 新的 myLocalObject
(这几乎是但不完全是复制构造函数) 然后指针丢失。
你也没有展示使用vector的代码,但是如果它不删除里面的指针,你会有更多的内存泄漏。
没有理由 almost-copy-constructor;编译器为您提供了更好的真实 copy-constructor.
更快更简单的方法是认识到这段代码根本不需要指针。
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
}
对于需要指针的情况,例如多态性,使用智能指针:
std::vector<std::unique_ptr<MyClass>> myClassArray; // smart pointer
myClassArray.push_back(make_unique<MyDerivedClass>(stuff));
std::unique_ptr
会在对象从 vector 中移除时自动释放对象(除非您明确将其移出),避免需要记住 delete
.
类.
对象的实例化基本上有2种方式
动态分配(在堆上)
MyClass* myLocalObject = new MyClass(); // dynamically allocates memory and assigns memory address to myLocalObject
循环示例:
class MyClass
{
private:
int _num;
std::string _name;
public:
// let's add an additional constuctor having default values
// that makes it easier later on
// if parameters are passed, they are used, or the defalt values, if not
// can call it like MyClass(), MyClass(123), or MyClass(456,"hello")
// you might want to pass larger data as reference, to avoid copying it
MyClass(int num=0, std::string name = "some default text")
: _num(num), _name(name)
{}
};
std::vector<MyClass*> myClassArray; // your array of pointers
for (int i = 0; i < 3; i++)
myClassArray.push_back(new MyClass(i, "test"));
// delete
for (auto& pointerToElement : myClassArray) // get a reference to each element (which is a pointer)
delete pointerToElement; // delete element (call's destructor if defined)
在这种情况下,您必须 delete myLocalObject;
否则会发生内存泄漏。
与其处理原始指针,尤其是当刚接触 C++ 时,我建议使用智能指针,它可以为您处理内存管理。
自动分配(尽可能在堆栈上)
MyClass myLocalObject = MyClass(); // automatically allocates memory and creates myLocalObject
这通常发生在堆栈上(如果可能)。这要快得多,而且您不必处理动态内存管理
循环示例:
std::vector<MyClass> myClassArray; // now "containg" the memory of objects itself
for (int i = 0; i < 3; i++)
{
myClassArray.emplace_back(i, "test"); // we use emplace_back instead to construct instances of type MyClass directly into the array
}
// no deletion required here
// destructors of each element will be called (if defined) when myClassArray is deleted automatically when out of scope
还有其他方法,比如动态堆栈分配和其他黑魔法,但建议关注“标准”。
在处理大量数据的情况下,您可能需要使用 std::vector::reserve。结合 automatic/stack 分配,通过将内存分配限制为 1 个而不是每个元素 1 个,有助于加快速度。
希望对您有所帮助:-)
我是 C++ 的新手,尝试了解如何在 C++ 中创建和使用 class。 为此,我有以下代码:
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
}
从网上找了一个类似的例子,试着理解一下。 我的意图是用新的 class 对象填充 myClassArray。 如果我使用 VisualStudio 2022 编译上面的代码,我不会出错,但我不确定它不会产生内存泄漏,或者是否有更快更简单的方法。
尤其是下面这行我不明白: MyClass myLocalObject = new MyClass();
myLocalObject是在栈上创建的,但是是用堆值初始化的(因为是new的)。如果使用 new 运算符, delete 必须应用在哪里?
感谢您的任何建议!
您在 MyClass myLocalObject = new MyClass();
处发生内存泄漏,因为 dynamically-allocated 对象用于 converting-construct 新的 myLocalObject
(这几乎是但不完全是复制构造函数) 然后指针丢失。
你也没有展示使用vector的代码,但是如果它不删除里面的指针,你会有更多的内存泄漏。
没有理由 almost-copy-constructor;编译器为您提供了更好的真实 copy-constructor.
更快更简单的方法是认识到这段代码根本不需要指针。
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
}
对于需要指针的情况,例如多态性,使用智能指针:
std::vector<std::unique_ptr<MyClass>> myClassArray; // smart pointer
myClassArray.push_back(make_unique<MyDerivedClass>(stuff));
std::unique_ptr
会在对象从 vector 中移除时自动释放对象(除非您明确将其移出),避免需要记住 delete
.
类.
对象的实例化基本上有2种方式动态分配(在堆上)
MyClass* myLocalObject = new MyClass(); // dynamically allocates memory and assigns memory address to myLocalObject
循环示例:
class MyClass
{
private:
int _num;
std::string _name;
public:
// let's add an additional constuctor having default values
// that makes it easier later on
// if parameters are passed, they are used, or the defalt values, if not
// can call it like MyClass(), MyClass(123), or MyClass(456,"hello")
// you might want to pass larger data as reference, to avoid copying it
MyClass(int num=0, std::string name = "some default text")
: _num(num), _name(name)
{}
};
std::vector<MyClass*> myClassArray; // your array of pointers
for (int i = 0; i < 3; i++)
myClassArray.push_back(new MyClass(i, "test"));
// delete
for (auto& pointerToElement : myClassArray) // get a reference to each element (which is a pointer)
delete pointerToElement; // delete element (call's destructor if defined)
在这种情况下,您必须 delete myLocalObject;
否则会发生内存泄漏。
与其处理原始指针,尤其是当刚接触 C++ 时,我建议使用智能指针,它可以为您处理内存管理。
自动分配(尽可能在堆栈上)
MyClass myLocalObject = MyClass(); // automatically allocates memory and creates myLocalObject
这通常发生在堆栈上(如果可能)。这要快得多,而且您不必处理动态内存管理
循环示例:
std::vector<MyClass> myClassArray; // now "containg" the memory of objects itself
for (int i = 0; i < 3; i++)
{
myClassArray.emplace_back(i, "test"); // we use emplace_back instead to construct instances of type MyClass directly into the array
}
// no deletion required here
// destructors of each element will be called (if defined) when myClassArray is deleted automatically when out of scope
还有其他方法,比如动态堆栈分配和其他黑魔法,但建议关注“标准”。
在处理大量数据的情况下,您可能需要使用 std::vector::reserve。结合 automatic/stack 分配,通过将内存分配限制为 1 个而不是每个元素 1 个,有助于加快速度。
希望对您有所帮助:-)