2010-10-11 11 views
19

Nó không phải là rõ ràng những gì xảy ra nếu tôi xóa một phương pháp ảo trong C++ 0x:Xóa chức năng ảo trong C++ 0x

virtual int derive_func() = delete; 

Điều này có nghĩa lớp này và tất cả những gì được thừa hưởng từ nó có thể không xác định/thực hiện phương thức derive_func()? Hoặc là lỗi biên dịch/bất hợp pháp này?

+1

@GMan Tôi đồng ý rằng có thể không có lý do chính đáng nào nhưng đề xuất dường như cho phép rõ ràng. – flownt

+0

@flownt: Rất tiếc, xin lỗi. :) Đã xóa trên bạn. – GManNickG

+2

Nó có tác dụng tạo ra RTTI hay không. Tương đương trong C++ hiện tại là có một destructor ảo rỗng? –

Trả lời

14

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete A deleted virtual function may not override a non-deleted virtual function and vice-versa. nghĩa của nó khá vô dụng (như tôi đọc nó ít nhất) việc sử dụng chỉ có giá trị sẽ là:

struct A{ 
    virtual void b() = delete; 
}; 
struct B:A{ 
    virtual void b() = delete; 
}; 

đó là hoàn toàn vô dụng, vì chức năng không bao giờ có thể được gọi. đối với các chức năng không ảo, việc sử dụng được hợp lý hơn

CHỈNH SỬA để hoàn toàn rõ ràng đây là mối quan hệ CÓ THỂ, trẻ em có thể không thực hiện và bạn không thể xóa ảo không được thừa kế.

+1

Lạ. Có lẽ nó buộc các phương pháp trở nên lỗi thời? nhưng vẫn ... –

+1

có bắt buộc phải lưu trữ thông tin RTTI không? – KitsuneYMG

+0

Vì vậy, nó giống như câu trả lời đã xóa của tôi? – Klaim

4

flownt got it right, nhưng tôi muốn chỉ ra rằng trong trận chung kết C++ 11 dự thảo (N3337), ngôn ngữ tương ứng đã chuyển sang phần 10,3 # 16:

Một chức năng với một định nghĩa xóa thì không ghi đè hàm không có định nghĩa đã xóa. Tương tự, hàm không có định nghĩa đã xóa sẽ không ghi đè hàm có định nghĩa đã xóa. 2

Có vẻ như khá rõ ràng với tôi (phần 8.4.3 # 1) rằng một xóa nét nào trong thực tế được tính là một định nghĩa , và trong thực tế một định nghĩa inline, có nghĩa là định nghĩa đã xóa thỏa mãn 10.3 # 11:

Hàm ảo được khai báo trong một lớp phải được xác định hoặc khai báo trong lớp đó hoặc cả hai; nhưng không cần chẩn đoán. 2

Tuy nhiên, có vẻ như các triển khai hiện tại không đồng ý. Đây là trường hợp thử nghiệm của tôi:

struct Base { 
    virtual void bar(); 
    virtual void foo() = delete; 
}; 

void Base::bar() { } // a definition of the first non-inline virtual function 
int main() { Base b; } 
  • Clang sản xuất một chương trình unlinkable: Base::foo được đề cập trong vtable cho Base. Và nếu bạn hoán đổi thứ tự của foobar, trình liên kết than phiền rằng toàn bộ vtable bị thiếu (vì Clang nghĩ rằng foo là một hàm không phải là nội tuyến không có định nghĩa). I filed this as a bug; chúng ta sẽ thấy những gì các nhà phát triển nghĩ.

  • GCC than phiền về việc "sử dụng" số foo ở cuối đơn vị dịch, khi nó tạo ra vtable; nhưng nó xác định chính xác bar là hàm thành viên ảo không nội dòng đầu tiên, bất kể thứ tự của foobar.

+0

Theo dõi tuyệt vời. –