2016-12-15 344 views
-1

当试图使用std::static_pointer_cast向下转换std::shared_ptr时,发生段错误,其中派生类还包含std::weak_ptr将shared_ptr向下转换为包含weak_ptr C++的派生类11

这里是一个MWE:

#include<iostream>                                                 
#include<memory>                                                  

struct Base {};                                                  

struct Derived : Base                                                
{                                                     
    std::weak_ptr<int> wp;                                               
};                                                     

int main()                                                   
{                                                     
    auto pB = std::make_shared<Base>();    // Create a pointer to Base class instance                              
    auto pD = std::static_pointer_cast<Derived>(pB); // Downcast this to a Derived class instance                             
    auto pint = std::make_shared<int>(0);   // Define a pointer to an integer                                

    std::cout << "assigning pint" << std::endl;                                          
    pD->wp = pint;         //Attempt to assign member of Derived                                         
    std::cout << "Did not segfault" << std::endl;                                         

    return 0;                                                  
} 
+3

你'static_pointer_cast'是未定义行为当然,因为'pB'实际上并不指向'pD'类型的对象。 –

+0

我明白了。我清楚地误解了'std :: static_pointer_cast'的作用。 你会如何建议我实现我想要的,即将底层的'Base'升级为'Derived',最后产生一个'std :: shared_ptr '? –

+0

问题是你实际上在构造'Base',所以当你将它转换到Derived'(它工作)时,你在访问它时会得到未定义的行为,因为从来没有真正分配过Derived的内存。在这种情况下,你会遇到段错误。 – Donnie

回答

0

这编译和工作,但我不知道它是否是 '好' 的C++ 11

#include<iostream>                                            
#include<memory>                                             

struct Base {};                                             

struct Derived : Base                                            
{                                                 
    Derived(std::shared_ptr<Base> b) : Base{*b} {}                                    
    std::weak_ptr<int> wp;                                          
};                                                

int main()                                              
{                                                 
    auto pB = std::make_shared<Base>();    // Create a pointer to Base class instance                         
    auto pD = std::make_shared<Derived>(pB);                                      
    auto pint = std::make_shared<int>(0);   // Define a pointer to an integer                           

    std::cout << "assigning pint" << std::endl;                                     
    pD->wp = pint;                                            
    std::cout << "Did not segfault" << std::endl;                                     

    return 0;                                              
}   
+0

是的,这是合法的。但是很不清楚。如果您想要移动数据,那么该代码将无法解决(它会创建一个副本)。 –

相关问题