2012-07-10 3 views
10

Die Code-Snippet erzeugt unter einem Fehler:C++ abstrakte Klasse Parameterfehler Abhilfe

#include <iostream> 

using namespace std; 

class A 
{ 

public: 

    virtual void print() = 0; 
}; 

void test(A x) // ERROR: Abstract class cannot be a parameter type 
{ 
    cout << "Hello" << endl; 
} 

Gibt es eine Lösung/Abhilfe für diesen Fehler andere/besser als

virtual void print() = 0; 

mit

ersetzt
virtual void print() = { } 

EDIT: Ich möchte in der Lage sein, jede Klasse zu übergeben, die die Basisklasse A als Parameter erweitert und implementiert, indem Sie Poly verwenden Morphismus (d.h. A* x = new B() ; test(x);)

Prost

+0

Abstarct-Klasse per Definition sollte nicht von selbst instanziiert werden. Diese Methoden müssen von den abgeleiteten Klassen überschrieben werden. Nur neugierig, was versuchst du damit zu erreichen? – Mahesh

+1

Ich möchte etwas wie A x = new B() machen und jede Klasse extending/implementieren A übergeben. Ich hätte die Frage besser angeben sollen, denke ich. – Cemre

+1

Bevor wir versuchen, eine Lösung/Abhilfe zu finden, müssen wir das Problem verstehen. Die Idee, eine abstrakte Klasse als "nach Wert" -Parameter zu übergeben, macht überhaupt keinen Sinn. Was versuchst du zu machen? – AnT

Antwort

20

Da Sie eine abstrakte Klasse nicht instanziieren können, ist das Übergeben einer nach Wert fast sicher ein Fehler; müssen Sie es durch Zeiger oder durch Verweis übergeben:

void test(A& x) ... 

oder

void test(A* x) ... 

von Wert Passing in object slicing führen wird, mit fast haben unerwartet (in einem schlechten Weg) Konsequenzen, die garantiert wird, so Der Compiler markiert dies als Fehler.

+1

Ich würde sagen, es ist sicherlich garantiert. –

+0

@LuchianGrigore Sie haben Recht, das Slicing wird immer ausgeführt, auch wenn keine zusätzlichen Datenelemente entfernt werden, weil die vtable von der der Basisklasse abgeschnitten wird. – dasblinkenlight

3

Natürlich die Signatur ändern:

void test(A& x) 
//or 
void test(const A& x) 
//or 
void test(A* x) 

Der Grund Ihrer Version funktioniert nicht, weil ein Objekt vom Typ A nicht logisch keinen Sinn. Es ist abstrakt. Das Übergeben eines Verweises oder Zeigers geht um diesen herum, weil der tatsächliche Typ, der als Parameter übergeben wird, nicht A ist, sondern eine implementierende Klasse von A (abgeleitete konkrete Klasse).