Wie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten Klasse initialisieren?

Lesezeit: 5 Minuten

Wie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten
amrhassan

Warum kann ich das nicht?

class A
{
public:
    int a, b;
};

class B : public A
{
    B() : A(), a(0), b(0)
    {
    }

};

  • Fragst du warum Sie können das nicht tun, was eine Frage des Sprachdesigns ist, oder fragen Sie wie um diese Sprachbeschränkung zu umgehen?

    – Rob Kennedy

    13. September 2011 um 17:14 Uhr

  • Ich dachte, dass es eine Art speziellen Weg gibt, den ich nicht kenne, ohne den Basiskonstruktor verwenden zu müssen.

    – amrhassan

    13. September 2011 um 20:48 Uhr

  • Die Member der Basisklasse sind bereits initialisiert, wenn Ihr Konstruktor der abgeleiteten Klasse ausgeführt wird. Du kannst zuordnen sie, wenn Sie Zugriff haben, oder rufen Sie Setter für sie auf, oder Sie können Werte für sie an den Basisklassenkonstruktor liefern, wenn es einen geeigneten gibt. Das einzige, was Sie kann nicht was in der entwickelten Klasse zu tun ist, ist, sie zu initialisieren.

    – Benutzer207421

    23. August 2017 um 0:25 Uhr

1646617212 234 Wie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten
In Silico

Sie können nicht initialisieren a und b in B weil sie keine Mitglieder sind B. Sie sind Mitglieder von Aalso nur A kann sie initialisieren. Sie können sie öffentlich machen und dann eine Zuweisung vornehmen B, aber das ist keine empfohlene Option, da es die Kapselung zerstören würde. Erstellen Sie stattdessen einen Konstruktor in A erlauben B (oder eine Unterklasse von A) um sie zu initialisieren:

class A 
{
protected:
    A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
    // Change "protected" to "public" to allow others to instantiate A.
private:
    int a, b; // Keep these variables private in A
};

class B : public A 
{
public:
    B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
    {
    } 
};

  • Während Ihr Beispiel richtig ist, ist Ihre Erklärung irreführend. Es ist nicht so, dass du es nicht kannst initialisieren a und b in B::B() weil sie privat sind. Sie können sie nicht initialisieren, da sie keine Mitglieder von sind class B. Wenn Sie sie öffentlich gemacht oder geschützt hätten, könnten Sie das tun zuordnen sie im Körper von B::B().

    – R. Samuel Klatschko

    13. September 2011 um 17:22 Uhr

  • Darüber hinaus macht Ihre Lösung Klasse A nicht aggregiert, was wichtig sein könnte und daher erwähnt werden muss.

    – Gene Buschujew

    13. September 2011 um 17:28 Uhr

  • @R Samuel Klatchko: Guter Punkt. Als ich die Antwort schrieb, tippte ich zunächst “Sie können nicht zugreifen a und b…” und änderte es in “Sie können nicht initialisieren …”, ohne sicherzustellen, dass der Rest des Satzes Sinn macht. Beitrag bearbeitet.

    – In silico

    13. September 2011 um 17:30 Uhr


  • @Gene Bushuyev: Die Klasse im Originalcode in der Frage ist keine Aggregat (es gibt nicht statische private Mitglieder)

    – David Rodríguez – Dribeas

    13. September 2011 um 18:04 Uhr

  • @David – richtig, das ist ein Benutzerfehler, und ich versuche, zu den Absichten des Benutzers zu gelangen, indem ich oberflächlich überspringe.

    – Gene Buschujew

    13. September 2011 um 18:20 Uhr

1646617213 808 Wie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten
NPE

Abgesehen von der Tatsache, dass sie es sind privateseit a und b sind Mitglieder von Asie sollen durch initialisiert werden AKonstruktoren von , nicht von den Konstruktoren einer anderen Klasse (abgeleitet oder nicht).

Versuchen:

class A
{
    int a, b;

protected: // or public:
    A(int a, int b): a(a), b(b) {}
};

class B : public A
{
    B() : A(0, 0) {}
};

1646617214 493 Wie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten
Violette Giraffe

Irgendwie hat niemand den einfachsten Weg aufgelistet:

class A
{
public:
    int a, b;
};

class B : public A
{
    B()
    {
        a = 0;
        b = 0;
    }

};

Sie können nicht auf Basiselemente in der Initialisierungsliste zugreifen, aber der Konstruktor selbst kann wie jede andere Elementmethode darauf zugreifen public und protected Mitglieder der Basisklasse.

  • Hübsch. Gibt es irgendeinen Nachteil dabei?

    – Wander3r

    9. Januar 2019 um 15:29 Uhr

  • @SaileshD: Es kann sein, dass Sie ein Objekt mit einem kostspieligen Konstruktor initialisieren. Es wird zuerst standardmäßig initialisiert, wenn die Instanz von B zugewiesen ist, dann wird es innerhalb der zugewiesen BDer Konstruktor von . Aber ich denke auch, dass der Compiler das noch optimieren kann.

    – Violette Giraffe

    10. Januar 2019 um 11:36 Uhr

  • Innen class A darauf können wir uns nicht verlassen a und b initialisiert wird. Jede Implementierung von class C : public Akönnte beispielsweise vergessen anzurufen a=0; und gehen a nicht initialisiert.

    – Sparkofska

    2. Dezember 2019 um 7:49 Uhr

  • @Wander3r Ein weiterer Nachteil ist, dass nicht alle Klassen Zuweisungsoperatoren haben. Einige können nur konstruiert, aber nicht zugeordnet werden. Dann bist du fertig…

    – Martin Pecka

    3. Juni 2020 um 16:09 Uhr

  • Natürlich Dies ist keine Initialisierung. “Die Unterklassen können sie immer noch neu initialisieren” ist nur Unsinn, C++ hat keine solche Operation wie die Neuinitialisierung.

    – Ben Voigt

    8. Dezember 2021 um 17:31 Uhr

Wie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten
Mannisch Srivastava

# include<stdio.h>
# include<iostream>
# include<conio.h>

using namespace std;

class Base{
    public:
        Base(int i, float f, double d): i(i), f(f), d(d)
        {
        }
    virtual void Show()=0;
    protected:
        int i;
        float f;
        double d;
};


class Derived: public Base{
    public:
        Derived(int i, float f, double d): Base( i, f, d)
        {
        }
        void Show()
        {
            cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
        }
};

int main(){
    Base * b = new Derived(10, 1.2, 3.89);
    b->Show();
    return 0;
}

Dies ist ein funktionierendes Beispiel für den Fall, dass Sie die Datenelemente der Basisklasse initialisieren möchten, die im Objekt der abgeleiteten Klasse vorhanden sind, während Sie diese Werte per Push-Schnittstelle über den Konstruktoraufruf der abgeleiteten Klasse übertragen möchten.

Während dies in seltenen Fällen nützlich ist (wenn das nicht der Fall wäre, hätte die Sprache es direkt erlaubt), werfen Sie einen Blick auf die Basis von Member Idiom. Es ist keine codefreie Lösung, Sie müssten eine zusätzliche Vererbungsebene hinzufügen, aber es erledigt die Arbeit. Um Boilerplate-Code zu vermeiden, könnten Sie verwenden Boost-Implementierung

Warum kannst du es nicht? Weil die Sprache es Ihnen nicht erlaubt, die Mitglieder einer Basisklasse in der Initialisiererliste der abgeleiteten Klasse zu initialisieren.

Wie können Sie dies erreichen? So was:

class A
{
public:
    A(int a, int b) : a_(a), b_(b) {};
    int a_, b_;
};

class B : public A
{
public:
    B() : A(0,0) 
    {
    }
};

Aggregierte Klassen, wie A in Ihrem Beispiel A a {0,0}; , müssen ihre Member öffentlich haben und dürfen keine benutzerdefinierten Konstruktoren haben. Sie werden mit einer Initialisierungsliste initialisiert, z B() : A({0,0}){}oder in deinem fall

. Die Member der Basisaggregatklasse können im Konstruktor der abgeleiteten Klasse nicht einzeln initialisiert werden. class A

961610cookie-checkWie kann ich Elementvariablen der Basisklasse im Konstruktor der abgeleiteten Klasse initialisieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy