我可以通过 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 - 我们真的没有足够的信息来解决问题
是的。