2017-12-27 111 views
8

Các mã sau đây cũng được biên soạn:Sử dụng = mặc định trong ý nghĩa của = xóa

struct B { 
    B(int) {} 
}; 

struct D : B { 
    D() = default; 
}; 

Cho đến khi tôi phải tạo một thể hiện của lớp D:

D d; // error: use of deleted function 'D::D()' 

Có lý do nào đó (trường hợp sử dụng) để cho phép = default cho hàm xây dựng của D, khi nó thực sự hoạt động như = delete;?

+0

Nếu bạn thay đổi B, D sẽ tự động làm điều đúng. –

+0

Bạn đang sử dụng trình biên dịch nào?Có thể đó là vì cấu trúc của bạn trống và không làm gì, do đó trình biên dịch bỏ qua nó hoàn toàn như được định nghĩa với '= default'? –

+1

g ++ 5.1.0 'lưu ý: 'D :: D()' bị xóa hoàn toàn vì định nghĩa mặc định sẽ bị lỗi:' và 'lỗi: không có hàm nào phù hợp để gọi 'B :: B()'' –

Trả lời

11

g++ đưa ra một lời giải thích thoải mái trong các lỗi:

bla.cpp:6:5: note: ‘D::D()’ is implicitly deleted because the default definition would be ill-formed: D() = default;

Các constructor mặc định sẽ cố gắng để xây dựng tất cả các bộ phận của D. Bạn không có trường nào, nhưng nó có một số B ban đầu - không có một hàm tạo trống nào, chỉ có một trường là int.

Hành vi mặc định có ý nghĩa - D không được có hàm tạo trống, trừ khi nó nêu rõ int để xây dựng B và trình biên dịch không muốn đoán. Nếu không, bạn sẽ có một đối tượng D, và tùy thuộc vào những gì xảy ra trong B constructor B có thể chứa rác, ví dụ nếu khởi tạo một lĩnh vực.

Tôi không chắc chắn nếu bạn có nghĩa là câu hỏi của bạn theo nghĩa đen khi bạn hỏi tại sao điều này "phép", như các nhà xây dựng B mặc định sẽ bị xóa, nhưng tôi có thể nghĩ đến hai lý do:

  1. này hành vi được xác định rõ, và không có lý do gì để không cho phép nó. Phát hiện lỗi chỉ khi bạn cố gắng xây dựng một cái gì đó bất hợp pháp được thực hiện anyway.
  2. Đó là linh hoạt hơn - thay đổi B để có một constructor mặc định sẽ tự động cho phép D để có một.
6

Is there any reason (use case) to allow = default for D's constructor, when it's actually works as = delete;?

Nó không làm việc như =delete. Nó nói chỉ là những gì nó phải nói. Mà bạn rõ ràng muốn trình biên dịch tạo ra việc thực hiện mặc định.

Nó chỉ như vậy sẽ xảy ra rằng trình biên dịch tạo ra người ta phải được xác định bị xóa. Bởi vì hàm tạo mặc định của B bị xóa hoàn toàn.

+0

Tôi biết rằng '= xóa' không phải là' = mặc định', nhưng có một sự khác biệt trong trường hợp particalar của tôi? Tôi khá chắc chắn rằng không có gì thay đổi ngữ nghĩa nếu tôi thay đổi '= default' thành' = delete'. Liệu tôi có sai? – alexolut

+2

@alexolut - Chức năng sẽ bị xóa theo một trong hai cách. Nguyên nhân là khác nhau. Nếu trong tương lai 'B' nhận được một c'tor mặc định,' D' cũng sẽ. Nếu bạn phẳng xóa nó, nó sẽ không. Một số sẽ nói đó là một sự khác biệt lớn về ngữ nghĩa. – StoryTeller

1

B có một constructor không mặc định (constructor của nó có một đối số mà không có một giá trị mặc định).

Các nguồn gốc D lớp do đó không có một constructor mặc định, constructor mặc định của nó bị xóa (như trình biên dịch không thể tạo một constructor cho D rằng có thể gọi B(int) constructor của lớp cha của nó.)

D() = default; chỉ nói rằng bạn muốn hàm khởi tạo mặc định cho D và như được mô tả ở trên, hàm tạo mặc định sẽ bị xóa.

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