从基类的共享\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
- 也许您忘记将
设置为虚拟?IDKstart()
- 我们确实没有足够的信息来解决这个问题
是的。请更正语法错误(例如类定义后缺少
;
)。另外,在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";
}
}
}