1162 Stimmen

Kann ich in C++ einen Konstruktor von einem anderen Konstruktor aus aufrufen (Konstruktorverkettung durchführen)?

Als C# Entwickler bin ich es gewohnt, Konstruktoren zu durchlaufen:

class Test {
    public Test() {
        DoSomething();
    }

    public Test(int count) : this() {
        DoSomethingWithCount(count);
    }

    public Test(int count, string name) : this(count) {
        DoSomethingWithName(name);
    }
}

Gibt es eine Möglichkeit, dies in C++ zu tun?

Ich habe versucht, den Klassennamen aufzurufen und das Schlüsselwort "this" zu verwenden, aber beides schlägt fehl.

3voto

V15I0N Punkte 386

Dieser Ansatz kann für einige Arten von Klassen funktionieren (wenn sich der Zuweisungsoperator "gut" verhält):

Foo::Foo()
{
    // do what every Foo is needing
    ...
}

Foo::Foo(char x)
{
    *this = Foo();

    // do the special things for a Foo with char
    ...
}

2voto

Pantelis Sopasakis Punkte 1867

Ich schlage die Verwendung eines private friend Methode, die die Anwendungslogik des Konstruktors implementiert und die von den verschiedenen Konstruktoren aufgerufen wird. Hier ist ein Beispiel:

Angenommen, wir haben eine Klasse namens StreamArrayReader mit einigen privaten Feldern:

private:
    istream * in;
      // More private fields

Und wir wollen die beiden Konstruktoren definieren:

public:
    StreamArrayReader(istream * in_stream);
    StreamArrayReader(char * filepath);
    // More constructors...

Die zweite macht einfach von der ersten Gebrauch (und natürlich wollen wir die Implementierung der ersten nicht duplizieren). Idealerweise würde man gerne so etwas tun wie:

StreamArrayReader::StreamArrayReader(istream * in_stream){
    // Implementation
}

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    StreamArrayReader(&instream);
    instream.close();
}

Dies ist jedoch in C++ nicht zulässig. Aus diesem Grund können wir eine private freundliche Methode wie folgt definieren, die das implementiert, was der erste Konstruktor tun soll:

private:
  friend void init_stream_array_reader(StreamArrayReader *o, istream * is);

Jetzt hat diese Methode (weil sie ein Freund ist) Zugriff auf die privaten Felder von o . Dann wird der erste Konstruktor:

StreamArrayReader::StreamArrayReader(istream * is) {
    init_stream_array_reader(this, is);
}

Beachten Sie, dass dadurch keine Mehrfachkopien für die neu erstellten Kopien erstellt werden. Die zweite wird:

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    init_stream_array_reader(this, &instream);
    instream.close();
}

Das heißt, Anstatt dass ein Konstruktor einen anderen aufruft, rufen beide einen privaten Freund auf!

0voto

warren Punkte 30258

Wenn ich Ihre Frage richtig verstehe, fragen Sie, ob Sie mehrere Konstruktoren in C++ aufrufen können?

Wenn es das ist, wonach Sie suchen, dann ist das nicht möglich.

Sie können natürlich mehrere Konstruktoren mit jeweils eindeutigen Argument-Signaturen haben und dann den gewünschten Konstruktor aufrufen, wenn Sie ein neues Objekt instanziieren.

Sie können sogar einen Konstruktor mit standardisierten Argumenten am Ende haben.

Man darf aber nicht mehrere Konstruktoren haben und dann jeden davon einzeln aufrufen.

0voto

XPD Punkte 1042

Beim Aufruf eines Konstruktors wird tatsächlich Speicher zugewiesen, entweder vom Stack oder vom Heap. Der Aufruf eines Konstruktors in einem anderen Konstruktor erzeugt also eine lokale Kopie. Wir ändern also ein anderes Objekt, nicht das, auf das wir uns konzentrieren.

-1voto

gyula Punkte 7

Es wäre einfacher zu testen, als zu entscheiden :) Versuchen Sie dies:

#include <iostream>

class A {
public:
    A( int a) : m_a(a) {
        std::cout << "A::Ctor" << std::endl;    
    }
    ~A() {
        std::cout << "A::dtor" << std::endl;    
    }
public:
    int m_a;
};

class B : public A {
public:
    B( int a, int b) : m_b(b), A(a) {}
public:
    int m_b;
};

int main() {
    B b(9, 6);
    std::cout << "Test constructor delegation a = " << b.m_a << "; b = " << b.m_b << std::endl;    
    return 0;
}

und kompilieren Sie es mit 98 std: g++ main.cpp -std=c++98 -o test_1

werden Sie sehen:

A::Ctor
Test constructor delegation a = 9; b = 6
A::dtor

also :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X