2010-11-26 11 views
1

Ich habe eine Klasse wie folgt:C++ Vererbung Problem

Class A 
{ 
    virtual int doSomethingCool() = 0; 
}; 

Class B : public A 
{ 
    int doSomethingCool(); 
}; 

Nun das Problem mag, ich habe eine Reihe von Klassen haben Whcih auf A als Schnittstelle abhängig sind. Ich muss den Prototyp der Funktion für eine der abgeleiteten Klassen ändern. d. h. ich muss einen Parameter übergeben.

Class C: public A 
{ 
int doSomethingCool(int param); 
}; 

Irgendwelche Vorschläge, wie kann ich dies erreichen können?

+1

ist das C++ wirklich? – Chubsdad

+0

Ich habe mit Pseudocode vereinfacht. –

+2

Wenn eine zweite Klasse etwas anderes benötigt, bedeutet das entweder, dass es eine andere Schnittstelle ist oder die ursprüngliche Schnittstelle falsch ist. – David

Antwort

2

Nein, Sie müssen es nicht zur Basisklasse hinzufügen.

class A 
{ 
public: 
    virtual int doSomethingCool() = 0 {} 
}; 

class B : public A 
{ 
public: 
    int doSomethingCool() {return 0;} 
}; 

class C: public A 
{ 
private: 
    int doSomethingCool(); // hide base class version! 
public: 
    int doSomethingCool(int param) {return param;} 
}; 

Sie noch doSomethingCool() wenn durch eine Basisklasse Zeiger getan anrufen:

struct A 
{ 
    virtual int doSomethingCool() = 0; 
}; 

struct A_specific : A 
{ 
    virtual int doSomethingCoolWithThis(int i) = 0; 
}; 

class ConcreteA : public A 
{ 
    int doSomethingCool() { return 0; } 
}; 

class ConcreteA_specific : public A_specific 
{ 
    int doSomethingCool() { return 0; } 
    int doSomethingCoolWithThis(int param) { return param; } 
}; 

Dann würde ich programmieren:

C c; 
//c.doSomethingCool(); // doesn't work, can't access private member 
c.doSomethingCool (42); 
A &a = c; 
a.doSomethingCool(); 
//a.doSomethingCool (42); // doesn't work, no member of A has that signature 
0

Stellen Sie die Funktion doSomethingCool() den Parameter int in A ein.

class A 
{ 
public: 
    virtual void doSomethingCool(int param) = 0; 
}; 
+0

Das würde die Abhängigkeiten anderer Klassen in A brechen. –

+0

@Ricko: Ja, aber wenn Sie die Parameterliste der Klasse 'C' ändern, überschreibt das nicht Methode - es versteckt es.Wenn Sie beabsichtigen, die 'doSomethingCool()' Methode von der Klasse 'A' in der Klasse' C' zu überschreiben, wird es nicht tun, was Sie denken, dass es tut. Und da die Klasse "A" abstrakt ist, können Sie keine Instanzen von "C" erstellen, da Sie das parameterlose 'doSomethingCool()' noch nicht implementiert haben. –

0

Es gibt kein Problem. Du kannst es schaffen. Die einzige Einschränkung ist, dass sie nicht als Überschreibung der virtuellen Funktion der Basisklasse behandelt wird.

class A 
{ 
public: 
    virtual void doSomethingCool() = 0; 
}; 

class B : public A 
{ 
public: 
    void doSomethingCool(); 
}; 

class C: Public A 
{ 
public: 
    void doSomethingCool(int param); 
}; 


int main(){} 

Während also technisch möglich ist, können Sie wirklich wollen bei der Gestaltung Ihrer Interface-Klasse A.

Eine Option relook kann ein Standardargument zu A :: doSomethingCool

virtual void doSomethingCool(int = 0) = 0; 
bieten zu
+0

[Das überschreibt nicht die Funktion in der Basisklasse, es verbirgt es] (http://www.parashift.com/c++faq-lite/strange-inheritance.html#faq-23.9), was ich bin ziemlich sicher ist nicht, was das OP beabsichtigte. –

+0

@In silico: Dein Kommentar und mein Update haben sich gekreuzt – Chubsdad

+0

Ah, ich habe gerade deine Bearbeitung gesehen. :-) –

1

Fügen Sie es der Schnittstelle hinzu und verwenden Sie es als Standard, um die vorhandene Methode aufzurufen. Sie müssen nicht den Standard tun, aber machen Sie es nicht rein, sonst müssen alle abgeleiteten Klassen implementieren. Es ist vielleicht besser, es nicht zu definieren oder zu werfen. Hängt davon ab, was du erreichen willst.

class A 
{ 
public: 
    virtual int doSomethingCool() = 0; 
    virtual int doSomethingCool(int param) {doSomethingCool()}; 
}; 
+0

Beachten Sie, dass die Klasse 'C' immer noch die parameterlose' doSomethingCool() 'reine virtuelle Funktion implementieren muss oder Sie keine Instanzen von' C' erstellen können. –

0

Dies ist nicht syntaktisch korrekt C++.

Nein, Sie können keinen Prototyp ändern. Wie würde es verwendet werden? Was wäre der Wert des Parameters, wenn die nichtparametrische Version aufgerufen würde?

0

ich einen anderen, spezifischeren, Schnittstelle eingeführt würden die richtige Schnittstelle:

int main() 
{ 
    const A& a1 = ConcreteA(); 
    const A_specific& a2 = ConcreteA_specific(); 

    a1.doSomethingCool(); 
    a2.doSomethingCool(); 
    a2.doSomethingCoolWithThis(2); 
} 

Nur um dir eine andere Idee zu geben ;-)

Viel Glück!