Es ist explizit im Standard nicht erlaubt, auch wenn es einige Versionen von VisualStudio erlauben.
C++ Standard-7.1.5.3 Ausgearbeitt Typdeklarierer Absatz 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. ]
I erkennt den Code, oben als ein Muster mit einer Klasse zu versiegeln (die Verlängerung nicht erlauben). Es gibt eine andere Lösung, die die Erweiterung nicht wirklich blockiert, die aber unbemerkt von der Klasse ausgeht. Wie in ADOBE Source Library gesehen:
namespace adobe { namespace implementation {
template <class T>
class final
{
protected:
final() {}
};
}}
#define ADOBE_FINAL(X) private virtual adobe::implementation::final<T>
mit der Nutzung:
class Sealed : ADOBE_FINAL(Sealed)
{//...
};
Während es Erweiterung ermöglicht es, wenn Sie es wirklich zwingen:
class SealBreaker : public Sealed, ADOBE_FINAL(Sealed)
{
public:
SealBreaker() : adobe::implementation::final<Sealed>(), Sealed() {}
};
Es wird verhindern, dass Benutzer versehentlich es tun.
EDIT:
Der bevorstehende C++ 11-Standard ermöglicht es Ihnen, eine Art Argument mit einer etwas anderen Syntax anfreunden:
gefunden
template <typename T>
class A {
// friend class T; // still incorrect: elaborate type specifier
friend T; // correct: simple specifier, note lack of "class"
};
... wieder erlaubt C++ 11 das Schlüsselwort "final", zum Beispiel: class X final {...} (oder Sie können einzelne virtuelle Funktionen endgültig machen). In jedem Fall habe ich den Code oben ("Freund T;") mit g ++ 4.8.4 _without_ the -std = C++ 11-Flag versucht und es kompiliert gut. –