2017-12-19 4 views
0

Ich habe diesen Code:Passing abgeleitete Klasse eine Funktion der Basisklasse Argument

#include <iostream> 

class Base { 
    public: 
    virtual void sayHello() { 
    std::cout << "Hello world, I am Base" << std::endl; 
    } 
}; 

class Derived: public Base { 
    public: 
    void sayHello() { 
    std::cout << "Hello world, I am Derived" << std::endl; 
    } 
}; 

void testPointer(Base *obj) { 
    obj->sayHello(); 
} 

void testReference(Base &obj) { 
    obj.sayHello(); 
} 

void testObject(Base obj) { 
    obj.sayHello(); 
} 

int main() { 
    { 
    std::cout << "Testing with pointer argument: "; 
    Derived *derived = new Derived; 
    testPointer(derived); 
    } 
    { 
    std::cout << "Testing with reference argument: "; 
    Derived derived; 
    testReference(derived); 
    } 
    { 
    std::cout << "Testing with object argument: "; 
    Derived derived; 
    testObject(derived); 
    } 
} 

Die Ausgabe lautet:

Testing with pointer argument: Hello world, I am Derived 
Testing with reference argument: Hello world, I am Derived 
Testing with object argument: Hello world, I am Base 

Meine Frage ist, warum sowohl der Zeiger Fall void testPointer(Base *obj) und der Referenzfall void testReference(Base &obj) gib das Ergebnis der abgeleiteten Instanz von void sayHello() zurück, aber nicht und den Fall, dass die Kopie passiert? Was soll ich tun, damit der Kopiervorgang das Ergebnis der abgeleiteten Klassenfunktion void sayHello() zurückgibt?

+1

Ihr Argument "Testing with reference" ruft "testObject" anstelle von "testReference" auf. –

+3

Mögliches Duplikat von [Was ist Objekt-Slicing?] (Https://stackoverflow.com/questions/274626/what-is-object-slicing) –

+0

@RaymondChen Danke, dass der Referenzfall als Zeiger funktioniert. Aber für die Weitergabe durch Kopie gibt es wahrscheinlich keine Möglichkeit, die Implementierung der abgeleiteten Klassenfunktion aufzurufen. – Pekov

Antwort

1

Eine Funktion, die eine Referenz oder einen Zeiger verwendet, bezieht sich auf das übergebene Originalobjekt, während by-value Argumente eine Kopie Ihres Objekts erstellen. Da Sie nur das Basisteil kopieren (da es ein Basisobjekt benötigt), arbeiten Sie am Ende mit einer Kopie nur des Basisteils, und es verhält sich wie eine Basis, weil es eine Basis ist.

Dieses "Nur-Basis" -Kopieren wird "Slicing" genannt, da es nur einen Teil Ihres Objekts kopiert und den abgeleiteten Teil "abschneidet".

Verwandte Themen