从基类的shared_ptr中获取对象

get object from a shared_ptr of a base class

本文关键字:获取 取对象 ptr 基类 shared      更新时间:2023-10-16

我可以通过 c++ 中的smart_ptr实现规则多态性吗?

我有这两个结构:

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

在另外 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;
...
};
}

方法setPtr()将使用类型std::shared_ptr<Derived_namespace::ESM>调用,然后onStart()。因此,当调用onStart()时,m_base不应为 null。

具体问题在评论中。感谢任何帮助,我也想知道在使用智能指针进行多态性方面的一般良好实践。谢谢!!

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

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

class Animal {
public:
virtual ~Animal() = default;
virtual void speak() {
std::cout << "I am an animal.n"; 
}
};

我可以为狗、猫和牛覆盖此方法:

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";
}
};

现在我有了这个,我可以写一个让动物说两次的函数:

void speakTwice(Animal& animal) {
animal.speak();
animal.speak();
}

由于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();
}

将其与weak_ptr一起使用:

这也非常简单,下面的示例将告诉您指针是空还是过期。

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"; 
}
}
}

为什么您的代码遇到问题

您没有提供足够的代码让我们找出问题,尽管以下是一些可能性:

  • 您没有为m_base分配任何内容,因此锁定它时为空
  • 也许你忘了把start()虚拟的?IDK
  • 我们真的没有足够的信息来解决问题

是的。