Warum erzeugt der geschützte Konstruktor einen Fehler in diesem Code?
Eine Frage zu protected-Konstruktor. Ich habe gelernt, dass der geschützte Konstruktor kann verwendet werden, in der abgeleiteten Klasse. Wie auch immer, ich fand den code unten ein Fehler vorliegt. Warum geschieht es so?
class A
{
protected:
A(){}
};
class B: public A {
public:
B() {
A* f=new A(); //Why it is not working here
}
};
InformationsquelleAutor der Frage skydoor | 2010-03-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies hat nichts zu tun mit Konstruktoren speziell. Das ist nur, wie
protected
access funktioniert.Den Weg
protected
zugriffsspezifizierer arbeitet, ermöglicht es der abgeleiteten KlasseB
Zugriff auf die Inhalte ein Objekt der Basis-KlasseA
nur, wenn das Objekt der KlasseA
ist ein Unterobjekt der KlasseB
. Das bedeutet, dass die einzige Sache, die Sie tun können, in Ihrem code, um den Zugriff auf den InhaltA
durchB
: Sie können auf die Mitglieder desA
durch einen Zeiger vom TypB *
(oder eine Referenz vom TypB &
). Aber Sie nicht Zugriff auf die gleichen Mitglieder die durch einen Zeiger vom TypA *
(oder ReferenzA &
).Betrachten Sie das folgende Beispiel
In der oben
B::foo
können Sie auf Basis-MitgliedA::i
durch die Verwendung von einfach nuri
syntax. Dies entspricht der Verwendungthis->i
syntax. Beide funktionieren, da der Zeigerthis
TypB *
d.h. Sie sind aufA::i
gründlich ein Zeiger vom TypB *
. Das ist genau das, was dieprotected
zugriffsspezifizierer soll, zu ermöglichen. Der Zugriff überpb
pointer funktioniert aus dem gleichen Grund.Jedoch, wenn Sie die "convert" -
this
Zeiger auf TypA *
können Sie nicht mehr zugreifenA::i
durch das neue Zeiger, auch wenn Sie immer noch versuchen, Zugriff auf Sie sehr gleichen member wie vorher.Bei Anwendung auf Konstruktoren, die
protected
zugriffsspezifizierer hat eine sehr spezifische Wirkung: eine protected-Konstruktor kann nur verwendet werden, zu initialisieren, Basis-Klasse Unterobjekte. Es kann nicht verwendet werden, zu initialisieren, die eigenständige Objekte (das ist, was Sie versuchen zu tun). In anderen Worten, protected Konstruktoren sind ein weiterer Weg, um die Umsetzung des Konzepts abstrakte Klasse in C++ (zusammen mit rein virtuellen Methoden). Wenn die Konstruktoren der Klasse geschützt sind, dann ist Ihre Klasse effektiv abstrakte. Sie können es nicht verwenden, um zu definieren, unabhängige Objekte "von außen". (Natürlich, das gilt nicht, innerhalb von Freunden, als auch innerhalb der Klasse selbst).InformationsquelleAutor der Antwort AnT
Wenn eine Basisklasse einen protected-Konstruktor, Sie können nicht instanziieren Sie die Klasse direkt. Aber Sie können dies tun, rufen Sie den Konstruktor der Basisklasse Konstruktor:
Einen direkten Aufruf des Konstruktors, wie unten gezeigt, gibt die folgenden Fehler mit gcc version 4.1.2:
Jedoch, dieser Aufruf zum Konstruktor, gibt keinen Fehler:
Der Grund dafür ist, dass der zweite Aufruf ruft die Eine () - Konstruktor durch Vererbung, was erlaubt ist. Aber hier wird versucht, explizit eine neue Instanz erstellen, der Eine() durch den Aufruf der Konstruktor direkt:
Das mag unintuitiv, da B sollte in der Lage sein, um Zugriff auf Einen Konstruktor, weil B erbt von A. Allerdings, wenn Sie deklarieren Sie einen Konstruktor geschützt in C++, Sie können nicht erstellen Sie eine Instanz der Klasse, außer durch Vererbung, oder eine Freund-Beziehung.
InformationsquelleAutor der Antwort James Thompson
Lassen Sie mich meine Antwort in den Schritten:
1) Konstruktoren nicht Vererbt bekommen und deshalb in der abgeleiteten Klasse, Sie kann nicht mehr geritten werden.
2) Konstruktoren aufgerufen werden und nicht genannt.
3) Wenn Sie erklärt haben, eine einfache Funktion in Einem sagen protected void print() und dann versucht, Sie anzurufen, es in B, Es würde gearbeitet haben. Dies geschieht bcoz, B geerbt hat diese Funktion.
4), Wenn Sie so etwas tun b : a(), werden Sie den Aufruf der Konstruktor-und das ist erlaubt.
5) Versuchen Sie B ein Freund der Klasse Eines und dann starten und sehen, ob es funktioniert.
Hoffe, das hilft.
InformationsquelleAutor der Antwort Duleb
Hatte ich die gleiche Frage wie diese, und dieser link machen mir klar.
cppreference sagt wie diese:
InformationsquelleAutor der Antwort waterd