2008-08-20 5 views
22

Có ai nhận thức được một tính năng hoặc kỹ thuật ngôn ngữ trong C++ để ngăn chặn một lớp con từ trên một phương pháp cụ thể trong lớp cha mẹ?Có cách nào để ngăn chặn một phương thức bị ghi đè trong các lớp con không?

class Base { 
public: 
    bool someGuaranteedResult() { return true; } 
}; 

class Child : public Base { 
public: 
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ } 
}; 

Mặc dù nó không phải là ảo, đây vẫn được phép (ít nhất là trong các trình biên dịch Metrowerks Tôi đang sử dụng), tất cả các bạn nhận được là một thời gian biên dịch cảnh báo về ẩn phi ảo chức năng thừa hưởng X.

Trả lời

12

Một vài ý tưởng:

  1. Hãy chức năng của bạn tin.
  2. Không làm cho chức năng của bạn trở nên ảo. Điều này không thực sự ngăn cản chức năng bị che khuất bởi một định nghĩa khác.

Ngoài ra, tôi không biết tính năng ngôn ngữ sẽ khóa chức năng của bạn theo cách ngăn không bị quá tải và vẫn có thể được gọi thông qua con trỏ/tham chiếu đến lớp con .

Chúc may mắn!

+1

nhưng sau đó chúng tôi không thể gọi phương thức đó từ các lớp khác. ? – anshulkatta

+6

Lưu ý rằng có một thông số 'final' được thêm vào với C++ 11: http://stackoverflow.com/a/16906116/1025391 – moooeeeep

0

Nếu bạn định địa chỉ lớp con làm kiểu cha của nó, thì một hàm không phải ảo sẽ gọi phiên bản của lớp cha.

ví dụ:

Parent* obj = new Child(); 
-1

Phương pháp C++ là riêng tư và không thể ghi đè theo mặc định.

  • Bạn không có thể ghi đè một phương pháp riêng
  • Bạn không có thể ghi đè một virtual phương pháp phi

Bạn có lẽ đề cập đến quá tải?

+1

Chúng ta có thể ghi đè lên các hàm ảo riêng. –

2

một thời gian biên dịch cảnh báo về ẩn phi ảo chức năng thừa hưởng X.

thay đổi các thiết lập trình biên dịch của bạn để làm cho nó một lỗi thay vì cảnh báo.

0

Trừ khi bạn đặt phương thức ảo, lớp con không thể ghi đè lên nó. Nếu bạn muốn giữ cho các lớp con không gọi nó, hãy đặt nó ở chế độ riêng tư.

Vì vậy, theo mặc định C++ thực hiện những gì bạn muốn.

6

Âm thanh như những gì bạn đang tìm kiếm tương đương với ngôn ngữ Java final từ khóa prevents a method from being overridden by a subclass.

others ở đây có suggested, bạn thực sự không thể ngăn điều này. Ngoài ra, có vẻ như đây là một thay vì frequently asked question.

+4

Từ khóa 'final' được giới thiệu bởi C++ 11 (http://en.cppreference.com/w/cpp/language/final). Ngoài ra có một cái nhìn tại câu trả lời của tôi ở đây (http://stackoverflow.com/a/16896559/1025391) cho một ví dụ khác. – moooeeeep

+0

Đẹp, tôi không biết điều đó. Cảm ơn bạn đã tham khảo! –

0

Cố gắng ngăn người khác sử dụng cùng tên với chức năng của bạn trong phân lớp không khác nhiều so với cố gắng ngăn người khác sử dụng cùng tên hàm chung như bạn đã khai báo trong thư viện được liên kết.Bạn chỉ có thể hy vọng rằng người dùng có ý định sử dụng mã của bạn, chứ không phải người khác, sẽ cẩn thận với cách họ tham chiếu mã của bạn và họ sử dụng đúng loại con trỏ hoặc sử dụng phạm vi đủ điều kiện.

2

(a) Tôi không nghĩ chức năng riêng tư là giải pháp vì điều đó sẽ chỉ ẩn hàm lớp cơ sở khỏi lớp dẫn xuất. Lớp dẫn xuất có thể luôn định nghĩa một hàm mới có cùng chữ ký. (b) Làm cho hàm không ảo cũng không phải là giải pháp hoàn chỉnh bởi vì, nếu lớp dẫn xuất định nghĩa lại cùng hàm, ta có thể gọi hàm lớp dẫn xuất bằng cách biên dịch thời gian nghĩa là obj.someFunction() trong đó obj là một thể hiện của lớp dẫn xuất.

Tôi không nghĩ rằng có một cách để làm điều này. Ngoài ra, tôi muốn biết lý do quyết định của bạn để ngăn cấm các lớp học có nguồn gốc từ các hàm lớp cơ sở quan trọng.

0

Trong ví dụ của bạn, không có hàm nào bị ghi đè. Nó là thay vì ẩn (nó là một loại trường hợp thoái hóa của quá tải). Lỗi nằm trong mã lớp Trẻ em. Như csmba đã đề xuất, tất cả những gì bạn có thể làm là thay đổi các thiết lập trình biên dịch của bạn (nếu có thể); nó sẽ được miễn là bạn không sử dụng một thư viện của bên thứ ba ẩn các chức năng riêng của nó.

1

Tôi đoán trình biên dịch cảnh báo bạn về điều gì đang ẩn !! Nó thực sự bị ghi đè?

trình biên dịch có thể cung cấp cho bạn cảnh báo, nhưng khi chạy, phương thức lớp cha sẽ được gọi nếu con trỏ thuộc loại cấp độ gốc, bất kể loại thực tế của đối tượng mà nó trỏ đến.

Điều này thật thú vị. Hãy thử tạo một chương trình thử nghiệm nhỏ độc lập cho trình biên dịch của bạn.

0

Để làm rõ, hầu hết các bạn đã hiểu nhầm câu hỏi của mình. Anh ta không hỏi về phương pháp "ghi đè", anh ta hỏi liệu có cách nào để ngăn chặn "ẩn" hay không. Và câu trả lời đơn giản là "không có gì!".

Dưới đây là ví dụ của ông một lần nữa

lớp Chánh định nghĩa một hàm:

int foo() { return 1; } 

lớp trẻ em, kế thừa các phụ huynh xác định chức năng tương tự LẠI (không trọng):

int foo() { return 2; } 

Bạn có thể làm điều này trên tất cả các ngôn ngữ lập trình. Không có gì để ngăn chặn mã này biên dịch (ngoại trừ một thiết lập trên trình biên dịch). Điều tốt nhất bạn sẽ nhận được là cảnh báo rằng bạn đang ẩn phương thức của cha mẹ. Nếu bạn gọi lớp con và gọi phương thức foo, bạn sẽ nhận được 2. Bạn đã thực sự phá vỡ mã.

Đây là những gì anh ta đang hỏi.

0

Về mặt kỹ thuật, u có thể ngăn các chức năng ảo bị ghi đè. Nhưng bạn sẽ không bao giờ có thể thay đổi hoặc thêm nhiều hơn nữa. Đó không phải là giúp đỡ đầy đủ. Tốt hơn để sử dụng bình luận ở phía trước của chức năng như faq lite gợi ý.

28

Khi bạn có thể sử dụng trình chỉ định final cho các phương thức ảo (được giới thiệu với C++ 11), bạn có thể thực hiện. Hãy để tôi báo giá my favorite doc site:

Khi được sử dụng trong khai báo hàm ảo, cuối cùng xác định rằng chức năng có thể không bị ghi đè bởi các lớp dẫn xuất.

Thích nghi với ví dụ của bạn mà muốn được như:

class Base { 
public: 
    virtual bool someGuaranteedResult() final { return true; } 
}; 

class Child : public Base { 
public: 
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ } 
}; 

Khi biên soạn:

$ g++ test.cc -std=c++11 
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’ 
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’ 

Khi bạn đang làm việc với một trình biên dịch Microsoft, cũng có một cái nhìn tại các từ khóa sealed .

+0

tôi loại bỏ ảo và nó cho thấy tôi lỗi với chức năng gọi cơ bản ... công việc cuối cùng chỉ với các chức năng ảo? – AbhimanyuAryan

1

Tôi đã tìm kiếm tương tự và hôm qua đã đưa ra câu hỏi [khá cũ] này.

Hôm nay tôi tìm thấy từ khóa C++ 11 gọn gàng: final. Tôi nghĩ nó có thể hữu ích cho độc giả tiếp theo.

http://en.cppreference.com/w/cpp/language/final