2009-11-19 26 views
50

đây là một câu hỏi thực sự đơn giản nhưng tôi không thực hiện C++ đúng trong nhiều năm và vì vậy tôi là một chút bối rối bởi điều này. Ngoài ra, nó không phải là điều dễ nhất (đối với tôi ít nhất) để tìm kiếm trên internet, không phải để cố gắng.C++ Đối tượng không có mới

Tại sao điều này không sử dụng từ khóa new và cách hoạt động?

Về cơ bản, những gì đang xảy ra ở đây?

CPlayer newPlayer = CPlayer(position, attacker); 

Trả lời

42

biểu này:

CPlayer(position, attacker) 

tạo ra một đối tượng tạm thời loại CPlayer sử dụng các nhà xây dựng trên, sau đó:

CPlayer newPlayer =...; 

Các đề cập đối tượng tạm thời được sao chép bằng cách sử dụng constructor sao chép để newPlayer . Cách tốt hơn là viết những điều sau đây để tránh temporaries:

CPlayer newPlayer(position, attacker); 
+0

Tuyệt vời, cảm ơn. –

+5

Trình biên dịch thực sự có thể sẽ tối ưu hóa nó. Trong trường hợp đó, hàm tạo bản sao sẽ không được gọi. http://stackoverflow.com/questions/1758142/why-copy-constructor-is-not-called-in-this-case – BostonLogan

+4

Phép gán trong khai báo không kém hiệu quả hơn việc sử dụng cú pháp hàm tạo. Nếu họ đã có những tuyên bố riêng biệt, hơn là nhận xét về thời gian sẽ là chính xác. Bản chất là điều này tuyên bố một CPlayer (thường là trên stack) hơn là phân bổ không gian cho nó từ các cửa hàng miễn phí (đống). –

31

Trên đây xây dựng một đối tượng CPlayer trên stack, do đó nó không cần new. Bạn chỉ cần sử dụng new nếu bạn đang cố gắng phân bổ một đối tượng CPlayer trên heap. Nếu bạn đang sử dụng phân bổ heap, mã sẽ trông như thế này:

CPlayer *newPlayer = new CPlayer(position, attacker); 

Chú ý rằng trong trường hợp này chúng tôi đang sử dụng một con trỏ đến một đối tượng CPlayer rằng sẽ cần phải được làm sạch bởi một cuộc gọi phù hợp để delete . Một đối tượng được cấp phát trên ngăn xếp sẽ bị hủy tự động khi nó nằm ngoài phạm vi.

Trên thực tế nó sẽ được dễ dàng hơn và rõ ràng hơn để viết:

CPlayer newPlayer(position, attacker); 

Rất nhiều trình biên dịch sẽ tối ưu hóa phiên bản bạn đưa lên trên anyway và nó rõ ràng hơn để đọc.

+0

Tôi không nghĩ rằng điều này là chính xác: "Một đối tượng được phân bổ trên heap sẽ bị phá hủy tự động khi nó đi ra khỏi phạm vi." – Valentin

+0

Bạn đúng, tôi muốn viết "ngăn xếp" chứ không phải "đống". Cảm ơn bạn đã chỉ ra điều này. –

+0

Đồng ý về điều này. Chúng ta nên giữ mã C++ cùng kiểu với mã C. Vì vậy, 'CPlayer newPlayer (vị trí, kẻ tấn công);' tốt hơn 'CPlayer newPlayer = CPlayer (vị trí, kẻ tấn công);' nếu bạn muốn tạo một biến ngăn xếp. – tonga

4

newPlayer không được cấp phát động biến nhưng một ôtô, ngăn xếp phân bổ biến:

CPlayer* newPlayer = new CPlayer(pos, attacker); 

là khác nhau từ

CPlayer newPlayer = CPlayer(pos, attacker); 

newPlayer được cấp phát trên stack qua CPlayer bình thường (vị trí, kẻ tấn công) lời gọi hàm tạo, mặc dù hơi dài hơn bình thường

CPlayer newPlayer(pos, attacker); 

Đó là về cơ bản giống như nói:

int i = int(3); 
+2

Cẩn thận ở đây. Đó là một "khởi tạo bản sao". Đó là * không * một bài tập. – sellibitze

+0

Tôi đã sửa chữa, nó không phải là một nhiệm vụ; ngay cả các nhà xây dựng bản sao không có liên quan. Chỉnh sửa câu trả lời cho phù hợp. – digitalarbeiter

+2

Chắc chắn, ctor sao chép là (ít nhất là hợp lý) tham gia. Bạn sẽ nhận thấy rằng nếu bạn làm cho bản sao của bạn ctor riêng. Sau đó, việc khởi tạo bản sao này sẽ không hoạt động nữa. Tiêu chuẩn C++ yêu cầu một ctor sao chép có thể truy cập ngay cả khi trình biên dịch có thể tối ưu hóa bản sao. – sellibitze

8
CPlayer newPlayer = CPlayer(position, attacker); 

dòng này tạo ra một đối tượng địa phương mới của loại CPlayer. Mặc dù xuất hiện giống như chức năng của nó, điều này đơn giản gọi là hàm tạo của CPlayer. Không có thời gian hoặc sao chép có liên quan. Đối tượng có tên newPlayer tồn tại miễn là phạm vi nó được đính kèm. Bạn không sử dụng từ khóa new ở đây vì C++ không phải là Java.

CPlayer* newPlayer = new CPlayer(position, attacker); 

Dòng này tạo đối tượng CPlayer trên heap và xác định con trỏ có tên newPlayer để trỏ vào đó. Đối tượng sống cho đến khi có ai đó delete s.

+2

"Không có thời gian hoặc sao chép có liên quan" - Điều này là không chính xác đúng sự thật. Không có bảo đảm như vậy. Nhưng mọi trình biên dịch đều phải bỏ qua bản sao. – sellibitze

Các vấn đề liên quan