가상 메소드가있는 클래스 기반과 가상 메소드를 구현하는 구현 클래스가있는 경우 std :: shared_ptr을 캐스팅 할 방법이 있습니까 < 구현> &을 std :: shared <베이스> &으로 변환 하시겠습니까? 컴파일러는 const 참조를 허용하지만 비 const 참조의 경우 아래 코드의 "사례 A"에서처럼 실패합니다. 이 작업을 수행하는 쉬운 방법이 있습니까?shared_ptr의 non-const 참조를 기본 클래스로 캐스트하는 더 안전하고 안전한 방법이 있습니까?
그렇지 않은 경우 케이스 B에서 해결 방법 "questionable_cast"를 사용해도 안전합니까? 이 문제에
#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;
}
보너스 질문 : 왜이 기능이 다운 되었습니까? – bofjas
왜'questionable_cast' 함수에서와 같이 복사본을 만드는 대신 레퍼런스를 사용하려고합니까? 참조를 사용하면 카운터가 증가하지 않으므로 참조가 무효화 될 수 있습니다. –
나는 downvote하지 않았지만 가능한 이유 : * 왜 * 당신이 이것을하고 싶어합니까? 이와 같이 reinterpret_cast를 사용하면 엄격한 앨리어싱 규칙을 위반하게되므로 정의되지 않은 동작이됩니다. –