Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回make_shared<;基础>;,继承和强制转换为派生的未按预期工作?_C++_C++17_Shared Ptr_Make Shared - Fatal编程技术网

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
无关,与您创建错误类型有关。

啊,好的,有意义。谢谢。啊,好的,有意义。谢谢。相关:相关: