Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.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
从基类的共享\u ptr获取对象 < P> C++中的StaskYPPTR能实现多态性吗?_C++_Smart Pointers - Fatal编程技术网

从基类的共享\u ptr获取对象 < P> C++中的StaskYPPTR能实现多态性吗?

从基类的共享\u ptr获取对象 < P> C++中的StaskYPPTR能实现多态性吗?,c++,smart-pointers,C++,Smart Pointers,我有以下两种结构: struct Base{... // methods and variables }; struct D: Base{... // inherited methods and variable plus a few new methods }; 这两个结构的使用方式如下: typedef msm::back::state_machine<Base> ESM; //(Base_namespace::ESM) typedef msm::back::state_m

我有以下两种结构:

struct Base{... // methods and variables
};

struct D: Base{... // inherited methods and variable plus a few new methods
};
这两个结构的使用方式如下:

typedef msm::back::state_machine<Base>  ESM; //(Base_namespace::ESM)
typedef msm::back::state_machine<D>  ESM; //(Derived_namespace::ESM)
//The state_machine is from boost lib.
//They (ESM and ESM) are in different namespaces, so no problem using them
typedef msm::back::state_machine ESM//(基本名称空间::ESM)
typedef msm::back::state_machine ESM//(派生的名称空间::ESM)
//状态机来自boost lib。
//它们(ESM和ESM)位于不同的名称空间中,因此使用它们没有问题
在另外2节课上,我有:

Derived_namespace{
class derived_sth: public Base_namespace::sth
{
    public:
    //This method is used to assgin the m_base a share_ptr of type base ESM
    void setPtr(const std::shared_ptr<Derived_namespace::ESM> sm){
        m_base = std::dynamic_pointer_cast<Base_namespace::ESM>(sm);
    }
};
}

Base_namespace{
class sth
{
    public:
    void Base_namespace::onStart()
    {
        //!!!!!!!!
        //Here comes the problem, the variable sm turns out 
        //to be null, or some value that causes the following
        //if() statement to be false;
        //So how can I get the correct result?
        //!!!!!!!!
        std::shared_ptr<Base_namespace::ESM> sm = m_base.lock();
        if (sm)
        {
            sm->start();
        }
    }
    protected:
        std::weak_ptr<Base_namespace::ESM>  m_base;
    ...
};
}

派生的\u名称空间{
类派生的\u sth:公共基\u命名空间::sth
{
公众:
//此方法用于关联基本ESM类型的m_base a share_ptr
void setPtr(const std::shared_ptr sm){
m_base=std::动态指针投射(sm);
}
};
}
基本名称空间{
分类
{
公众:
void Base_命名空间::onStart()
{
//!!!!!!!!
//问题来了,变量sm变成了
//为null,或导致以下情况的某个值
//if()语句为假;
//那么如何才能得到正确的结果呢?
//!!!!!!!!
std::shared_ptr sm=m_base.lock();
如果(sm)
{
sm->start();
}
}
受保护的:
std::弱ptr m_基;
...
};
}
将使用类型
std::shared\u ptr
调用方法
setPtr()
,然后调用
onStart()
。因此,调用
onStart()
时,
m_base
不应为null


具体问题在评论中。非常感谢您的帮助,我还想知道关于智能指针多态性的一般良好实践。谢谢

使用智能指针的多态性与使用常规指针的多态性的工作方式相同

例如,假设我有一个类
Animal
,带有一个虚拟的
speak()
方法

class Animal {
   public:
    virtual ~Animal() = default;
    virtual void speak() {
        std::cout << "I am an animal.\n"; 
    }
};
因为
speak
是虚拟的,这将调用
speak
的正确版本:

Dog dog;
Cat cat;
Cow cow; 
// Prints:
// > Woof.
// > Woof.
speakTwice(dog); 
// Prints:
// > Meow.
// > Meow.             
speakTwice(cat);
// Prints:
// > Moo.
// > Moo.
speakTwice(cow); 
这仅仅是因为
speak
是虚拟的。除了使用
->

void speakTwice(std::shared_ptr<Animal> animal) {
    animal->speak();
    animal->speak();
}
为什么您的代码会遇到问题 您没有为我们提供足够的代码来解决问题,尽管存在以下几种可能性:

  • 您没有将任何内容分配给
    m_base
    ,因此锁定它时它为空
  • 也许您忘记将
    start()
    设置为虚拟?IDK
  • 我们确实没有足够的信息来解决这个问题

是的。

请更正语法错误(例如类定义后缺少
)。另外,在
derived_sth::setPtr()
中没有声明
m_base
。@MooingDuck可能是一个解决方案,但对我来说并不实际…@Henry:不要描述代码。因为
setPtr
中的
m_base
没有明显的方式来访问
m_base
,因为它们不是相互继承的。代码段中仍然存在许多语法错误。这是不可接受的:创建一个,否则如果这个问题很快就会被解决,请不要感到惊讶。我相信这个答案是错误的,因为
m_base
是一个
弱的ptr
,这与您在帖子中提到的任何内容无关。两种方式:(1)您没有回答问题的根源,(2)你似乎还不知道问题的根源是什么。我更喜欢结束那些没有足够信息安全回答的问题。我试图通过提供背景信息来提供帮助
Dog dog;
Cat cat;
Cow cow; 
// Prints:
// > Woof.
// > Woof.
speakTwice(dog); 
// Prints:
// > Meow.
// > Meow.             
speakTwice(cat);
// Prints:
// > Moo.
// > Moo.
speakTwice(cow); 
void speakTwice(std::shared_ptr<Animal> animal) {
    animal->speak();
    animal->speak();
}
void speakTwice(std::weak_ptr<Animal> const& animal) {
    if(animal.expired()) {
        std::cerr << "Animal was expired.\n";
        return;
    }
    auto ptr = animal.lock();
    if(ptr) {
        ptr->speak();
        ptr->speak();
    } else {
        std::cerr << "Animal was null.\n"; 
    }
}
}