[英]get object from a shared_ptr of a base class
Can I achieve regular polymorphism through smart_ptr in c++? 我可以在C ++中通过smart_ptr实现常规多态吗?
I have these 2 structs: 我有以下两个结构:
struct Base{... // methods and variables
};
struct D: Base{... // inherited methods and variable plus a few new methods
};
And these 2 structs will be used like this: 这两个结构将像这样使用:
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
And in another 2 classes, I have this: 在另外两个班级中,我有这个:
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;
...
};
}
The method setPtr()
will be called with type std::shared_ptr<Derived_namespace::ESM>
, then onStart()
. 方法setPtr()
调用类型为std::shared_ptr<Derived_namespace::ESM>
,然后onStart()
。 So the m_base
should not be null when onStart()
gets called. 因此,在onStart()
时, m_base
不应为null。
The specific question is in the comment. 具体问题在评论中。 Any help is appreciated and I also would like to know the general good practice when it comes to polymorphism with smart pointers. 感谢您的帮助,我也想了解有关使用智能指针进行多态性的一般良好做法。 Thanks!! 谢谢!!
Polymorphism with smart pointers works the same way that polymorphism with regular pointers does. 智能指针的多态性与常规指针的多态性相同。
For example, let's say I have a class Animal
with a virtual speak()
method. 例如,假设我有一个带有虚拟speak()
方法的Animal
类。
class Animal {
public:
virtual ~Animal() = default;
virtual void speak() {
std::cout << "I am an animal.\n";
}
};
I can override this method for dogs, cats, and cows: 我可以为狗,猫和牛重写此方法:
class Dog : Animal {
public:
void speak() override {
std::cout << "Woof.\n";
}
};
class Cat : Animal {
public:
void speak() override {
std::cout << "Meow.\n";
}
};
class Cow : Animal {
public:
void speak() override {
std::cout << "Moo.\n";
}
};
Now that I have this, I can write a function that makes the animal speak twice: 现在有了这个,我可以编写一个使动物说话两次的函数:
void speakTwice(Animal& animal) {
animal.speak();
animal.speak();
}
Because speak
is virtual, this will call the correct version of speak
: 因为speak
是虚拟的,这将调用正确版本的speak
:
Dog dog;
Cat cat;
Cow cow;
// Prints:
// > Woof.
// > Woof.
speakTwice(dog);
// Prints:
// > Meow.
// > Meow.
speakTwice(cat);
// Prints:
// > Moo.
// > Moo.
speakTwice(cow);
This only works because speak
is virtual. 这仅是有效的,因为 speak
是虚拟的。 And it works the same way with smart pointers, except using ->
除了使用->
之外,它与智能指针的工作方式相同。
void speakTwice(std::shared_ptr<Animal> animal) {
animal->speak();
animal->speak();
}
weak_ptr
: 将其与weak_ptr
一起使用: This is very straight-forward too, and the below example will tell you if the pointer was null or expired. 这也非常简单,下面的示例将告诉您指针是否为null或过期。
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";
}
}
}
You didn't provide enough code for us to figure out the issue, although these are some possibilities: 您可能没有提供足够的代码来帮助我们解决问题,尽管有以下几种可能:
m_base
, so it's null when you lock it 您没有为m_base
分配任何m_base
,因此将其锁定时为null start()
virtual? 也许您忘记了将start()
虚拟化? IDK IDK Yeah. 是的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.