7 Stimmen

Übergabe der abgeleiteten Klasse per Referenz an eine Funktion, die die Basisklasse als Parameter akzeptiert

Betrachten Sie den folgenden Code:

class A {
public:
    virtual ~A() { }

    virtual void print() const {
        std::cout << "In A" << std::endl;
    }
};

class B : public A {
public:
    B() { }
    virtual ~B() { }

    virtual void print() const {
        std::cout << "In B" << std::endl;
    }
};

void doSomething(A* a) {
    a->print();
}

void doSomething(const A a) {
    a.print();
}

int main()
{
    A* a = new B();
    doSomething(a);
    doSomething(B());
    return 0;
}

Warum gibt das folgende Ergebnis aus:

In B
In A

Aber wenn Sie doSomething zu doSomething(const A& a) ändern, gibt es aus:

In B
In B

12voto

Mike Seymour Punkte 242473

Dies ist als Slicing bekannt.

Beim Übergeben von A per Wert wird eine lokale Kopie erstellt, indem nur der A-Teil des Objekts des Aufrufers kopiert wird. Da dies sowohl einen statischen als auch einen dynamischen Typ von A hat, wird die Überschreibung von print gewählt.

Beim Übergeben per Referenz erhält die Funktion eine Referenz auf das Objekt des Aufrufers mit dynamischem Typ B, sodass diese Überschreibung gewählt wird.

Die Verwendung von abstrakten Basisklassen kann verwirrendes Verhalten wie dieses verhindern - sie können nicht direkt instanziiert werden und können daher nicht per Wert übergeben werden.

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