我可以在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
在另外两个班级中,我有这个:
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()
。因此,m_base
被调用时onStart()
不应为空。
具体问题在评论中。感谢您的帮助,我也想了解有关使用智能指针进行多态性的一般良好做法。谢谢!
答案 0 :(得分:-1)
具有智能指针的多态与具有常规指针的多态的工作方式相同。
例如,假设我有一个带有虚拟Animal
方法的类speak()
。
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 是的