C++ 返回make_shared<;基础>;,继承和强制转换为派生的未按预期工作?
考虑以下示例:以各种方式构造C++ 返回make_shared<;基础>;,继承和强制转换为派生的未按预期工作?,c++,c++17,shared-ptr,make-shared,C++,C++17,Shared Ptr,Make Shared,考虑以下示例:以各种方式构造共享\u ptr,并返回: #include <memory> #include <iostream> class Base { public: virtual ~Base() {} Base(int y) : y_(y) {} int y_; }; class Derived : public Base { public: Derived(int y, int z) : Base(y), z_(z) {}
共享\u ptr
,并返回:
#include <memory>
#include <iostream>
class Base
{
public:
virtual ~Base() {}
Base(int y) : y_(y) {}
int y_;
};
class Derived : public Base
{
public:
Derived(int y, int z) : Base(y), z_(z) {}
int z_;
};
std::shared_ptr<Base> A()
{
return std::shared_ptr<Base>(new Derived(1, 2));
}
std::shared_ptr<Base> B()
{
std::shared_ptr<Derived> result = std::make_shared<Derived>(Derived(1, 2));
return result;
}
std::shared_ptr<Base> C()
{
std::shared_ptr<Base> result = std::make_shared<Base>(Derived(1, 2));
return result;
}
std::shared_ptr<Base> D()
{
return std::make_shared<Base>(Derived(1, 2));
}
int main(int argc, char** argv)
{
// Works fine...
std::shared_ptr<Derived> resultA = std::dynamic_pointer_cast<Derived>(A());
// Works fine...
std::shared_ptr<Derived> resultB = std::dynamic_pointer_cast<Derived>(B());
// Does not cast to base? ...
std::shared_ptr<Derived> resultC = std::dynamic_pointer_cast<Derived>(C());
// Object returns fine (of type Base), but cannot be cast to Derived?
std::shared_ptr<Base> resultCBase = C();
std::shared_ptr<Derived> resultCDerived = std::dynamic_pointer_cast<Derived>(resultCBase);
// Does not cast to derived...
std::shared_ptr<Derived> resultD = std::dynamic_pointer_cast<Derived>(D());
return 0;
}
#包括
#包括
阶级基础
{
公众:
虚拟~Base(){}
基(int-y):y_u(y){
int y_;
};
派生类:公共基
{
公众:
派生(inty,intz):基(y),z_z{}
int z_2;;
};
std::共享_ptr A()
{
返回std::shared_ptr(新派生的(1,2));
}
std::共享_ptr B()
{
std::shared_ptr result=std::make_shared(派生的(1,2));
返回结果;
}
std::共享_ptr C()
{
std::shared_ptr result=std::make_shared(派生的(1,2));
返回结果;
}
std::共享_ptr D()
{
return std::make_shared(派生的(1,2));
}
int main(int argc,字符**argv)
{
//工作很好。。。
std::shared_ptr resultA=std::dynamic_pointer_cast(A());
//工作很好。。。
std::shared_ptr resultB=std::dynamic_pointer_cast(B());
//没有投到底部。。。
std::shared_ptr resultC=std::dynamic_pointer_cast(C());
//对象返回fine(类型为Base),但不能强制转换为派生?
std::shared_ptr resultCBase=C();
std::shared\u ptr resultcreided=std::dynamic\u pointer\u cast(resultbase);
//不强制转换为派生的。。。
std::shared_ptr resultD=std::dynamic_pointer_cast(D());
返回0;
}
总之:
返回std::make_shared
似乎工作正常,允许调用方正确地强制转换。(请参见A()
)
使用make_shared
创建派生类型,然后依靠隐式强制转换返回shared_ptr
工作,并允许调用者正确强制转换。(请参见B()
)
但是,对于C()
和D()
在使用make_-shared(派生(…)
时,构建了shared_-ptr
,但无法强制转换为std::shared_-ptr
我不熟悉make_shared
给出了什么(尽管其他答案暗示了更好的类型安全性和单一分配?),但它的性能或行为似乎与替换为std::shared_ptr(新t(…)
时不同
有人能给我解释一下这里发生了什么,为什么它没有像我预期的那样起作用(我猜我用错了,或者在使用它的时候我应该知道一些微妙的行为特征)
由于上述示例存在差异,A()
和B()
工作,但不包括C()
和D()
(假设我正确使用它)。。。为什么建议将make_shared
置于std::shared_ptr(新T(…)
之上,是否存在任何例外情况,这意味着不建议将其置于另一个之上
我不熟悉make_shared
提供了什么
它创建一个T
(在堆上,将其包装在共享的\u ptr
中)。它精确且仅创建T
。您的make_shared
调用相当于新基(派生(1,2)
。这将构造一个基
(通过从给定的派生
的基
子对象进行复制,通常称为“切片”,因为您只复制对象的一部分),因为这是您指定的类型
在那些shared\u ptr
s中没有Derived
,因此您不能dynamic\u pointer\u cast
但是,它的执行或行为似乎与替换为std::shared_ptr(新的t(…)
为什么建议make_shared
优于std::shared_ptr(新T(…)
std::shared_ptr(新基(派生的(1,2))
会有完全相同的问题。这与make_shared
无关,与创建错误类型有关
我不熟悉make_shared
提供了什么
它创建一个T
(在堆上,用shared\u ptr
包装它)。它精确且仅创建T
。您的make\u shared
调用相当于新基(派生的(1,2)
。这将构造一个Base
(通过从给定的派生的
的基
子对象进行复制,通常称为“切片”,因为您只是复制对象的一部分),因为这是您为其指定的类型
在那些shared\u ptr
s中没有Derived
,因此您不能dynamic\u pointer\u cast
但是,它的执行或行为似乎与替换为std::shared_ptr(新的t(…)
为什么建议make_shared
优于std::shared_ptr(新T(…)
std::shared_ptr(新基(派生的(1,2))
会有完全相同的问题。这与make_shared
无关,与您创建错误类型有关。啊,好的,有意义。谢谢。啊,好的,有意义。谢谢。相关:相关: