Wie kann ich von einer Friend-Funktion auf einen geschützten Konstruktor zugreifen?

8

Ich habe eine Klasse erstellt und möchte jeden, der ein Objekt erstellen möchte, dazu zwingen, unique_ptr zu verwenden. Dazu habe ich gedacht, den Konstruktor protected zu deklarieren und eine friend Funktion zu verwenden, die ein unique_ptr zurückgibt. Also hier ist ein Beispiel von dem, was ich tun möchte:

%Vor%

Ich habe etwas über Freund-Funktionen gelesen und ich habe verstanden, dass eine Freund-Funktion den Zugriff auf private / geschützte Mitglieder eines Objekts einer Klasse ermöglicht.

Kann ich mein Beispiel trotzdem machen?

Auch ohne Friend-Funktionen ist mein Ziel, den CreateA auf den only -Weg zu setzen, damit jemand ein Objekt erstellen kann.

BEARBEITEN

Ich ändere den Code ein bisschen. Ich habe nicht erwähnt, dass meine Klasse einen Template-Parameter benötigt. Das macht die Dinge scheinbar komplexer.

    
TheCrafter 24.11.2015, 19:18
quelle

3 Antworten

3

Sie können es so machen: -

%Vor%

Ausgabe: -

%Vor%

Wenn Sie die Funktion friend nicht verwenden möchten, können Sie die Funktion static & amp; nenn es so: -

%Vor%

BEARBEITEN: -

Als Antwort auf Ihre Bearbeitung habe ich das Programm & amp; es geht so: -

%Vor%

Einfach & amp; einfach !!! Aber denken Sie daran, dass Sie object of A nicht instanziieren können. Viel Glück !!!

    
Ankit Acharya 24.11.2015, 20:27
quelle
2

Die anderen Antworten schlagen vor, eine statische Template-Funktion zu verwenden, die meiner Meinung nach die beste Lösung ist, weil sie einfacher ist.

Meine Antwort erklärt, warum Ihr Freund-Ansatz nicht funktioniert hat und wie Sie den Freund-Ansatz richtig anwenden.

Es gibt zwei Probleme in Ihrem ursprünglichen Code. Zum einen ist make_unique nicht wirklich ein Freund von A , daher hat der Aufruf make_unique<A<T>>(myarg); keinen Zugriff auf den geschützten Konstruktor von A . Um dies zu vermeiden, können Sie stattdessen unique_ptr<A<T>>(new A(myarg)) verwenden. Theoretisch wäre es möglich, make_unique zu einem Freund zu erklären, aber ich bin mir nicht einmal sicher, welche Syntax dafür geeignet ist.

Das andere Problem ist das Problem der Template-Freunde . In einer Klassenvorlage deklariert friend <function-declaration> tatsächlich einen Freund, der keine Vorlage ist.

Die C ++ - FAQ schlägt zwei mögliche Problemumgehungen vor. Eine davon ist die Definition der Friend-Funktion inline. In diesem Fall kann die Funktion jedoch nur durch argumentabhängiges Nachschlagen gefunden werden. Aber da die Funktion A<T> (oder A<T> & ) nicht als Argument akzeptiert, kann sie niemals auf diese Weise gefunden werden. Diese Option ist also für Ihre Situation nicht praktikabel - sie ist eher für das Überladen von Operatoren geeignet.

Die einzige Lösung besteht darin, die Template-Funktion vor der Klassendefinition zu deklarieren (und optional zu definieren):

%Vor%

Hinweis: Es ist möglich, CreateA zu deklarieren, wo ich es definiert habe, und die Funktionsdefinition später zu setzen. Der von mir gepostete Code funktioniert jedoch - obwohl A nicht definiert ist, wenn new A<T>(myarg) in der Quelle angezeigt wird - weil CreateA erst beim Aufruf instanziiert wird, an diesem Punkt wird A definiert.

    
M.M 24.11.2015 22:12
quelle
2

Erstellen Sie eine statische Funktion, die den geschützten Konstruktor instanziiert.

%Vor%     
Nandu 24.11.2015 19:32
quelle

Tags und Links