Wenn Sie eine Klasse Base mit virtuellen Methoden und eine Klasse Implementierung haben, die die virtuellen Methoden implementiert, gibt es eine Möglichkeit, std :: shared_ptr < Implementierung zu std :: shared < Base> &? Der Compiler erlaubt dies für Const-Verweise, aber für nicht-const-Verweise schlägt es wie in "Case A" in dem folgenden Code fehl. Gibt es einen einfachen Weg, dies zu tun?Gibt es eine bessere/sichere Möglichkeit, eine nicht-konstante Referenz von shared_ptr auf eine Basisklasse zu übertragen?
Wenn nicht, wie sicher ist meine Problemumgehung "fraglich_cast" in Fall B?
#include <iostream>
#include <memory>
class Base
{
public:
virtual void set_value(int x) = 0;
};
class Implementation : public Base
{
public:
Implementation() : m_value(0) { }
void set_value(int x) override
{
m_value = x;
}
int get_value() const
{
return m_value;
}
private:
int m_value;
};
void do_something(std::shared_ptr<Base>& base)
{
base->set_value(5);
/// Code like this makes the non-const argument necessary
base = std::make_shared<Implementation>();
}
template <class T, class U>
std::shared_ptr<T>& questionable_cast(std::shared_ptr<U>& u)
{
/// This code is here to assure the cast is allowed
std::shared_ptr<T> tmp = u;
(void)tmp;
return *reinterpret_cast<std::shared_ptr<T>*>(&u);
}
int main()
{
std::shared_ptr<Implementation> a = std::make_shared<Implementation>();
// The following line causes a compiler error:
// invalid initialization of reference of type ‘std::shared_ptr<Base>&’ ...
// do_something(a);
// do_something(std::dynamic_pointer_cast<Base>(a));
// This is the workaround
do_something(questionable_cast<Base>(a));
std::cerr << "a = " << a->get_value() << std::endl;
return 0;
}
Bonus Frage: Warum wird dies downvoted? – bofjas
Warum versuchen Sie, dies mit einer Referenz zu tun, anstatt nur eine Kopie zu erstellen, wie Sie es in der Funktion "fragliche_Sendung" tun? Wenn Sie eine Referenz verwenden, wird der Zähler nicht erhöht und die Referenz kann ungültig gemacht werden. –
Ich habe nicht runtergestimmt, aber mögliche Gründe: * Warum * willst du das machen? Die Verwendung von reinterpret_cast ist eine Verletzung der strengen Aliasing-Regeln und somit ein undefiniertes Verhalten. –