C++ new关键字在使用上的注意点与区分

发布于:2024-05-10 ⋅ 阅读:(36) ⋅ 点赞:(0)

一、C++中new的作用

在C++中,new 关键字主要用于动态内存分配和对象的动态创建。

1、动态内存分配

new 关键字用于在堆上动态分配内存,创建对象或数组。它返回所分配内存的地址,并将该地址赋值给指针变量。

int* p = new int; // 分配一个整数的内存,并将地址赋值给指针 p

2、对象动态创建

new 关键字用于在堆上动态创建对象。与使用栈上对象的声明不同,动态创建的对象存储在堆内存中,需要使用 delete 关键字手动释放内存

MyClass* obj = new MyClass(); // 创建 MyClass 类的对象,并将地址赋值给指针 obj
delete obj;

int* arr = new int[10]; // 创建一个包含 10 个整数的数组
delete[] arr; // 删除数组

二、注意事项

1、内存泄漏

使用 new 关键字分配的内存需要手动释放,否则可能导致内存泄漏。或者可以使用智能指针(如 std::unique_ptr 或 std::shared_ptr)来管理动态分配的内存,以确保在发生异常时能够正确释放内存。

2、初始化

使用 new 创建对象时,可以选择是否调用对象的构造函数进行初始化。
如果不使用括号,则对象将使用默认构造函数进行初始化;如果使用括号,则会调用相应的构造函数进行初始化。

// 使用默认构造函数初始化对象
MyClass* obj1 = new MyClass;
// 调用带参数的构造函数进行初始化
MyClass* obj2 = new MyClass(10);

三、MyClass* obj1;和MyClass* obj1 = new MyClass();有什么区别

1、MyClass* obj1;

这种方式称为指针的声明。声明了一个指向 MyClass 类的指针变量 obj1,但没有创建对象,因此,obj1 是一个未初始化的指针,它指向的内存地址是未定义的,可能是空指针,也可能是指向任意地址的野指针。
在使用 obj1 之前,需要我们显式地分配内存并初始化指针。如果在使用 obj1 之前没有对其进行赋值,将会导致未定义的行为。

MyClass* obj1; // 声明一个指针变量,但未初始化
obj1->someMethod(); // 可能导致未定义的行为,因为指针未初始化

2、MyClass* obj1 = new MyClass();

这种方式称为动态内存分配和对象实例化。它通过使用 new 关键字在堆内存中动态分配了一个新的 MyClass对象,并将其地址赋给了指针变量 obj1。
这种方式创建了一个有效的对象实例,可以通过指针变量访问该对象的成员函数和成员变量。

MyClass* obj1 = new Singleton(); // 创建一个 MyClass对象,并将地址赋给指针变量 obj1
obj1->someMethod(); // 可以安全地调用对象的成员函数
delete obj1; // 手动释放动态分配的内存

总的来说,MyClass* obj1; 只是声明了一个指针变量而不创建对象,而 MyClass* obj1 = new MyClass(); 则创建了一个新的 MyClass对象,并将其地址赋值给了指针变量。

四、MyClass* obj1;和MyClass obj1;有什么区别

1、MyClass* obj1;

这是一个指针变量的声明,指向 MyClass 类型的对象。在声明时,只是创建了一个指针,而不是实际的对象。

2、MyClass obj1;

这是一个直接声明 MyClass 类型的对象,而不是指针,会自动调用默认构造函数来初始化它。而当对象离开作用域时会自动调用析构函数销毁对象。

总的来说,MyClass* obj1; 声明了一个指向 MyClass 类型对象的指针,而 MyClass obj1; 直接声明了一个 MyClass 类型的对象

五、MyClass* obj1 = new MyClass();、MyClass obj1;和static MyClass obj1;有什么区别

这三种声明方式主要区别在于对象的存储位置、生命周期和内存管理方式。

1、MyClass* obj1 = new MyClass();

使用 new 在堆上创建了一个 MyClass 类型的对象,并返回对象的地址,将其赋给指针 obj1。
对象的生命周期由程序员管理,需要手动调用 delete 来释放内存,否则可能导致内存泄漏。
对象的生存期不受限于声明它的作用域,可以在程序的任何地方访问。

2、MyClass obj1;

在栈上创建了一个 MyClass 类型的对象 obj1,并自动调用默认构造函数来初始化它。
对象的生命周期受限于其声明的作用域,当超出作用域时,会自动调用析构函数进行清理。
对象的内存管理由编译器自动处理,无需手动释放内存。

3、static MyClass obj1;

在全局或静态存储区中创建了一个 MyClass 类型的静态对象 obj1,并自动调用默认构造函数来初始化它。
静态对象在程序的整个生命周期内存在,其生命周期与程序的运行周期相同:在程序启动时就会被创建,并在程序结束时被销毁,不受作用域限制。
静态对象的内存管理由编译器自动处理,无需手动释放内存。


网站公告

今日签到

点亮在社区的每一天
去签到