2017-02-18 5 views
-3

Betrachten Sie die folgenden Klassen:shared_ptr mit mehreren Schnittstellen

class MyInterface1 { 
    ... 
}; 
class MyInterface2 { 
    ... 
}; 
class MyClass : public MyInterface1, public MyInterface2 { 
    ... 
}; 

Wenn ich den folgenden Code haben:

void MyFunction(shared_ptr<MyInterface1>& out); // returns a make_shared<MyClass> 

shared_ptr<MyInterface1> c1; 
shared_ptr<MyInterface2> c2; 
MyFunction(c1); 
c2 = c1; 

Ich bin nicht in der Lage c2 c1 zuzuordnen.

Zusätzlich wird es auch nicht kompilieren, wenn ich nur MyFunction(c2) aufrufen, was ich erwarten würde zu arbeiten, da MyClass von MyInterface1 und MyInterface2 abgeleitet ist. Dies scheint ein Compiler-Fehler (Visual Studio 2015 Update 3) zu sein, der sich zu teilen lohnt. Kann das jemand reproduzieren?

+4

Nein, das ist kein Compilerfehler. –

+5

Das hat nichts mit 'shared_ptr' zu tun, das funktioniert auch nicht mit rohen Zeigern. – tkausl

+1

'MyClass' kann ein' MyInterface1' oder ein 'MyInterface2' sein, aber es gibt keine Beziehung zwischen' MyInterface1' und 'MyInterface2. – user4581301

Antwort

-5

Sie können dies mit rohen Zeigern tun, aber es ist nicht möglich, mit einem shared_ptr zu tun. Nicht Shared_ptr verwenden, aber dies stattdessen tun:

void MyFunction(MyInterface1* out); // returns a new MyClass() 

MyInterface1* c1; 
MyInterface2* c2; 
MyFunction(c1); 
c2 = (MyInterface2*)c1; 
MyFunction((MyInterface1*)c2); 

Es ist sicherlich viel sauberer, einfacher und wartbar. Außerdem ist es schneller, da Sie shared_ptr nicht mehr verwenden und weniger Overhead haben. Verwenden Sie shared_ptr nicht, wenn Sie Wert auf Leistung legen.

+0

Nicht die beste Wahl aus mehreren Gründen. Vermeiden Sie C-Style-Casting - es kann Sie schlecht verletzen. Die Rückgabe eines neuen Objekts durch ein Argument mit einem Zeiger ohne expliziten Besitz ist in den meisten Fällen eine weitere schlechte Idee. – Dusteh

+1

Wirklich schlechter Rat, Alter. C-Style-Besetzung ist wie Gott sagt: "Vertrau mir. Ich weiß, was ich tue." Bessere Hoffnung, dass Gott recht hat, weil es richtig oder falsch passieren wird. In diesem Fall spielst du Gott und du liegst falsch. – user4581301

+0

Ich bin die einzige Person, die tatsächlich eine Lösung angeboten hat und alle anderen sagen, es ist eine schlechte Idee. Wenn es eine schlechte Idee ist, nehmen Sie es mit dem Schöpfer der Sprache auf. Das war keine Frage des Stils, also nimm deinen "heiligen Krieg" woanders hin ... Der Entwickler stellte eine Frage und ich war die einzige Person, die eine Antwort gab, während alle anderen nur Kommentare machten und keine wertvollen Einsichten hatten ... Nein Wunder, dass Leute ein Problem mit der Gemeinschaft haben. –

4

MyInterface1 und MyInterface2 sind völlig unabhängige Typen. Nur weil das Objekt von c1 hingewiesen hat einen Laufzeit-Typen, die von beiden erben, sind die statischen Typen nicht kompatibel, und Sie werden eine Besetzung verwenden haben einen zum anderen

shared_ptr<MyInterface1> c1; 
shared_ptr<MyInterface2> c2; 
MyFunction(c1); 
c2 = dynamic_pointer_cast<MyInterface2>(c1); 

Live Example

Dies wird zuweisen funktionieren natürlich nur, wenn der aktuelle dynamische Typ von *c1 von MyInterface2 erbt. Wie jede dynamic_cast, dynamic_pointer_cast wird nullptr zurückgeben, wenn die Typen nicht kompatibel sind.