Điều này rõ ràng không được phép trong tiêu chuẩn, ngay cả khi một số phiên bản của VisualStudio cho phép.
C++ chuẩn 7.1.5.3 xây dựng loại specifiers, đoạn 2
3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name. If the identifier resolves to a typedef-name or a template type-parameter, the elaborated-type-specifier is ill-formed. [Note: this implies that, within a class template with a template type-parameter T, the declaration friend class T; is ill-formed. ]
tôi nhận ra đoạn mã trên như một mô hình để đóng dấu (không cho phép gia hạn) một lớp. Có một giải pháp khác, điều đó không thực sự chặn phần mở rộng nhưng nó sẽ tự động mở rộng ra khỏi lớp. Như đã thấy trong ADOBE Source Library:
namespace adobe { namespace implementation {
template <class T>
class final
{
protected:
final() {}
};
}}
#define ADOBE_FINAL(X) private virtual adobe::implementation::final<T>
với việc sử dụng:
class Sealed : ADOBE_FINAL(Sealed)
{//...
};
Trong khi nó cho phép mở rộng nếu bạn thực sự buộc nó:
class SealBreaker : public Sealed, ADOBE_FINAL(Sealed)
{
public:
SealBreaker() : adobe::implementation::final<Sealed>(), Sealed() {}
};
Nó sẽ hạn chế người dùng từ sai lầm làm điều đó.
EDIT:
Tiêu chuẩn C++ 11 sắp tới không cho phép bạn làm bạn với một đối số kiểu với một cú pháp hơi khác nhau:
template <typename T>
class A {
// friend class T; // still incorrect: elaborate type specifier
friend T; // correct: simple specifier, note lack of "class"
};
Nguồn
2009-03-31 19:35:43
... sau đó một lần nữa, C++ 11 cho phép từ khóa "cuối cùng", ví dụ: lớp X final {...} (hoặc bạn có thể tạo các hàm ảo riêng lẻ cuối cùng). Trong mọi trường hợp, tôi đã thử đoạn mã trên ("friend T;") với g ++ 4.8.4 _without_ the -std = C++ 11 flag và nó biên dịch tốt. –