Gibt es einen Weg, Templates zu verwenden, um zu verhindern, dass eine Klasse in C ++ ableitbar ist

8

Ich muss verhindern, dass eine Klasse abgeleitet wird, also dachte ich mir, das ist etwas, das Boost bereits getan haben muss. Ich weiß, dass sie ein nicht kopierbares haben, sie müssen ein nicht ableitbares ...

haben

Stellen Sie sich meine Überraschung vor, als ich es nicht finden konnte ....

Das hat mich zum Nachdenken gebracht. Es muss einen Grund geben. Vielleicht ist es nicht möglich, Vorlagen zu verwenden.

Ich bin sicher, wenn es einfach war, ist es in den Boost-Bibliotheken.

Ich weiß, wie man es tut, ohne Vorlagen zu verwenden, d. h. eine Basisklasse mit einem privaten Konstruktor zu verwenden, d. h.

%Vor%

Oder so etwas ..

Vielleicht ist es die Vorwärtsreferenz, die das Problem verursacht, oder vielleicht gibt es keinen tragbaren Weg, um es zu erreichen.

Wie auch immer, ich bin nicht sicher, warum es nicht in Boost ist ..

Irgendwelche Ideen?

    
ScaryAardvark 21.01.2010, 17:53
quelle

6 Antworten

2

Unter der aktuellen Spezifikation ist es ausdrücklich verboten, ein Template-Argument zu "fristen", damit das Template nicht standardkonform wird. Boost würde wahrscheinlich so etwas seinen Bibliotheken nicht hinzufügen wollen. Ich glaube, dass diese Einschränkung in Ox jedoch gelockert wird, und es gibt Workarounds für Compiler.

    
Todd Gardner 21.01.2010, 17:57
quelle
7
Kevin Doyon 21.01.2010 17:56
quelle
3

In C ++ gibt es keine Möglichkeit, die Ableitung zu verhindern - Sie können diese Situation nicht verhindern:

%Vor%

Es gibt jedoch mehrere Möglichkeiten, die Instantiierung von Objekten vom Typ B zu verhindern. Ob dies den Aufwand wert ist, ist fraglich. Ich würde lieber dokumentieren, dass die Klasse A nicht zur Ableitung gedacht ist, und geben Sie ihr einen nicht-virtuellen Destruktor.

Beachten Sie außerdem, dass der Name _NonDeriv für die Implementierung in C ++ reserviert ist, wie auch alle Namen, die mit einem Unterstrich und einem Großbuchstaben beginnen. Sie dürfen solche Namen nicht in Ihrem eigenen Code erstellen.

    
anon 21.01.2010 17:57
quelle
1

Adobe hat dafür eine nicht perfekte Lösung mit Vorlagen.

Da Templates argumentabhängige Freunde [*] nicht deklarieren können, besteht das Problem darin, dass der Konstruktor geschützt ist und nicht der private. Es ist eine Teillösung, da es einen Compilerfehler auslöst, wenn jemand fälschlicherweise beschließt, von Ihrer Klasse abzuleiten, aber es ist keine vollständige Lösung, da jemand die Vererbung absichtlich erzwingen kann.

%Vor%

Der Vorteil ist, dass es templated sein kann (die Adobe-Bibliothek definiert tatsächlich ein Makro, das das "private virtuelle" vor dem zufälligen Leser verbirgt). Der Nachteil ist, dass es gebrochen werden kann.

Andererseits können Sie immer wieder tun, was C ++ FAQ für einige Fragen zum Blockieren einiger Funktionalitäten vorschlägt:

  

'Wie kann ich Menschen davon abhalten, ...': Schreibe einen Kommentar, um es nicht zu tun

     

'aber wie hemme ich andere wirklich davon ab ...': schreib einen Kommentar: Du wirst gefeuert wenn ...

     

'aber wie blockiere ich es eigentlich, falls sie dem Kommentar nicht folgen?': feuere sie

[*] Diese Einschränkung wird mit dem kommenden Standard, wann immer verfügbar, entfernt, wann immer er in Compilern implementiert wird ...

    
quelle
1

Einfach:

Machen Sie alle Konstruktoren privat:
Dann kann nobdy von dir ableiten. Natürlich fügt das andere Probleme hinzu, wie Sie eine Variable des Objekts nicht instanziieren können, aber es gibt Problemumgehungen für das Verwenden statischer öffentlicher Membermethoden und Freunde:

%Vor%     
Martin York 21.01.2010 19:23
quelle
0

Vielleicht verwandeln Sie Ihr Beispiel in eine Vorlage mit CRTP - das seltsam wiederkehrende Vorlagenmuster:

%Vor%

Könnte funktionieren ...

    
tony 21.01.2010 18:01
quelle

Tags und Links