2009-03-24 3 views
86

thể trùng lặp:
When should I use the new keyword in C++?Khi nào sử dụng "mới" và khi nào không sử dụng, trong C++?

Khi nào tôi nên sử dụng "mới" nhà điều hành trong C++? Tôi đến từ C#/Java nền và instantiating đối tượng là khó hiểu đối với tôi.

Nếu tôi đã tạo ra một lớp đơn giản gọi là "điểm", khi tôi tạo một điểm nên I:

Point p1 = Point(0,0); 

hoặc

Point* p1 = new Point(0, 0); 

Ai đó có thể làm rõ cho tôi khi sử dụng mới và khi nào thì không?

Duplicate của:

When should I use the new keyword in C++?

liên quan:

About constructors/destructors and new/delete operators in C++ for custom objects

Proper stack and heap usage in C++?

+0

trùng lặp - quá nhiều lần để đếm –

+0

như Neil đã nói, điều này đã được hỏi vô số lần. – Naveen

Trả lời

110

Bạn nên sử dụng new khi bạn muốn một vật thể tồn tại cho đến khi bạn delete nó. Nếu bạn không sử dụng new thì đối tượng sẽ bị hủy khi nó nằm ngoài phạm vi. Một số ví dụ của việc này là:

void foo() 
{ 
    Point p = Point(0,0); 
} // p is now destroyed. 

for (...) 
{ 
    Point p = Point(0,0); 
} // p is destroyed after each loop 

Một số người sẽ nói rằng việc sử dụng các new quyết định liệu đối tượng của bạn là trên heap hoặc stack, nhưng điều đó chỉ đúng của các biến khai báo bên trong hàm.

Trong ví dụ bên dưới vị trí của 'p' sẽ là nơi chứa đối tượng chứa Foo. Tôi thích gọi đây là phân bổ 'tại chỗ'.

class Foo 
{ 

    Point p; 
}; // p will be automatically destroyed when foo is. 

Cấp phát (và giải phóng) các đối tượng với việc sử dụng new là xa đắt hơn nếu họ được phân bổ tại chỗ nên việc sử dụng nó nên được giới hạn trong trường hợp cần thiết.

Ví dụ thứ hai khi phân bổ qua new là dành cho mảng. Bạn không thể * thay đổi kích thước của một mảng tại chỗ hoặc ngăn xếp tại thời gian chạy, do đó, nơi bạn cần một mảng kích thước chưa được xác định, nó phải được cấp phát qua mới.

Ví dụ:

void foo(int size) 
{ 
    Point* pointArray = new Point[size]; 
    ... 
    delete [] pointArray; 
} 

(* đánh dấu trước khi làm trống - có, có các tiện ích mở rộng cho phép phân bổ kích thước ngăn thay đổi).

+2

+1 Chỉ cần nhớ bạn cần phải tự xóa con trỏ mới xóa p1; –

+6

+1 tốt đẹp nhất. chỉ cần nhớ người đầu tiên có thể được viết là điểm p (0, 0); quá. cú pháp = .. có thể làm cho anh ta nghĩ rằng p bằng cách nào đó là một con trỏ được gán cái gì đó. –

+0

@Andrew Grant Nếu bạn phải sử dụng mới 'shared_ptr' hoặc' unique_prt'. đã được giới thiệu trong C++ 11 STL con trỏ được chia sẻ sẽ tự động lưu trữ sách. lưu ý cho mảng mặc định deleter được cung cấp bởi 'shared_ptr' gọi xóa, không xóa [] do đó sử dụng hàm lambda ' std :: shared_ptr p (new int [10], [] (int * p) { delete [ ] p; }); ' hoặc 'std :: shared_ptr p (new int [10], std :: default_delete ());' hoặc sử dụng helper được cung cấp từ unique_ptr trong đó kêu gọi xóa [ ] 'std :: unique_ptr p (new int [10], [] (int * p) { xóa [] p; }); ' – katta

9

Hãy xem this questionthis question để có một số câu trả lời hay về khởi tạo đối tượng C++.Ý tưởng cơ bản này là các đối tượng được khởi tạo trên heap (sử dụng mới) cần phải được làm sạch theo cách thủ công, các đối tượng được khởi tạo trên ngăn xếp (không có mới) sẽ tự động được dọn sạch khi chúng nằm ngoài phạm vi. Quay lại đầu trang

void SomeFunc() 
{ 
    Point p1 = Point(0,0); 
} // p1 is automatically freed 

void SomeFunc2() 
{ 
    Point *p1 = new Point(0,0); 
    delete p1; // p1 is leaked unless it gets deleted 
} 
1

Mới luôn được sử dụng để cấp phát bộ nhớ động, bộ nhớ này phải được giải phóng.

Bằng cách thực hiện tùy chọn đầu tiên, bộ nhớ đó sẽ được giải phóng tự động khi phạm vi bị mất.

Point p1 = Point(0,0); //This is if you want to be safe and don't want to keep the memory outside this function. 

Point* p2 = new Point(0, 0); //This must be freed manually. with... 
delete p2; 
4

Bạn nên sử dụng mới khi bạn muốn đối tượng được tạo trên heap thay vì ngăn xếp. Điều này cho phép một đối tượng được truy cập từ bên ngoài hàm hoặc thủ tục hiện tại, thông qua sự trợ giúp của con trỏ.

Nó có thể được sử dụng để bạn tra cứu con trỏ và quản lý bộ nhớ trong C++ vì đây là những thứ bạn không thể gặp phải trong các ngôn ngữ khác.

+0

Mới không đảm bảo phân bổ heap và chỉ đơn giản là tránh mới không đảm bảo phân bổ stack. –