2010-09-17 12 views
8

Khi bạn tạo một đối tượng mới trong C++ mà sống trên stack, (cách tôi đã chủ yếu là nhìn thấy nó), bạn làm như sau:C++ ngăn xếp biến và các biến đống

CDPlayer player; 

Khi bạn tạo một đối tượng trên đống bạn gọi new:

CDPlayer* player = new CDPlayer(); 

Nhưng khi bạn làm điều này:

CDPlayer player=CDPlayer(); 

nó tạo ra một chồng dựa đối tượng, b ut whats sự khác biệt giữa đó và ví dụ hàng đầu là gì?

+1

có thể trùng lặp của [Làm dấu ngoặc đơn sau tên loại có tạo sự khác biệt với mới không?] (Http://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make- a-different-with-new) – fredoverflow

Trả lời

20

Sự khác biệt là rất quan trọng với PODs (về cơ bản, tất cả được tích hợp trong các loại như int, bool, double, vv cộng với C-như cấu trúc và các đoàn thể xây dựng chỉ từ PODs khác), mà có sự khác biệt giữa khởi tạo mặc địnhkhởi tạo giá trị. Đối với PODs, một đơn giản

T obj; 

sẽ rời obj uninitialized, trong khi T() mặc định-khởi tạo các đối tượng. Vì vậy,

T obj = T(); 

là một cách hay để đảm bảo rằng đối tượng được khởi tạo đúng cách.

Điều này đặc biệt hữu ích trong mã mẫu, trong đó T có thể là POD hoặc loại không phải POD. Khi bạn biết rằng T không phải là loại POD, thì phải đủ T obj;.

Phụ Lục: Bạn cũng có thể viết

T* ptr = new T; // note the missing() 

(và tránh khởi của đối tượng được phân bổ nếu T là một POD).

+2

Các loại do người dùng định nghĩa cũng có thể là POD, trong trường hợp này, chúng sẽ hoạt động như các bản dựng sẵn khi không khởi tạo rõ ràng. –

+0

@Konrad: Bạn nói đúng, sự khác biệt giữa POD và không phải POD! Cảm ơn bạn đã chỉ ra điều này, tôi đã thay đổi câu trả lời của mình cho phù hợp. – sbi

+0

Trong C++ 0x, bạn có thể đảm bảo khởi tạo đúng với 'T obj {};'. – fredoverflow

8

Khi bạn tạo một đối tượng mới trong C++ mà sống trên stack, (...), bạn làm như sau:

CDPlayer player; 

Không nhất thiết trên stack: các biến khai báo theo cách này có tự động lưu trữ. Nơi họ thực sự đi phụ thuộc. Nó có thể nằm trên ngăn xếp (đặc biệt khi khai báo nằm bên trong một phương thức) nhưng nó cũng có thể ở đâu đó khác.

Hãy xem xét các trường hợp khai báo là bên trong một lớp:

class foo { 
    int x; 
}; 

Bây giờ việc lưu trữ x là nơi từng cá thể lớp được lưu trữ. Nếu nó được lưu trữ trên heap, sau đó như vậy là x:

foo* pf = new foo(); // pf.x lives on the heap. 
foo f; // f.x lives where f lives, which has (once again) automatic storage. 
+4

@Tony: Điều này thực sự trả lời câu hỏi? Nó có nghĩa là một bình luận bổ sung…. Nó không chạm vào sự khác biệt giữa mã đầu tiên và mã thứ ba của bạn, vì các câu trả lời khác đã thực hiện điều đó. –

0
CDPlayer* player = new CDPlayer(); 

Điều này thực sự làm là tạo ra một con trỏ trên stack và làm cho nó trỏ đến một đối tượng CDPlayer cấp phát trên heap.