调用派生类方法,当它被称为shared_ptr<Basic>
Call Derived class method when it's known as shared_ptr<Basic>
我坚信这是一个非常常见的面向对象的问题,但是google并没有给我一个答案。我希望,有人能给我指出正确的方法来摆脱死锁。我尽量了解和使用标准技术,避免重复发明。
总结如下:
class A {
protected:
int _A;
public:
virtual void commonMethod() = 0;
void methodForMember_A();
}
class B : public A {
protected:
int _B;
public:
virtual void commonMethod()
void methodForMember_B();
}
class C : public B {
protected:
int _C;
public:
virtual void commonMethod()
void methodForMember_C();
}
class Basic {
protected:
// B or C instance
shared_ptr<A> _smth;
public:
Basic(shared_ptr<A> a_ptr) : _smth(a_ptr);
// calls A/B/C->commonMethod();
void commonMethod();
}
// Which works with B
class MoreSpecific : public Basic {
public:
MoreSpecific(shared_ptr<B> b_ptr) : Basic(b_ptr);
// calls b->methodForMemberB();
void specificMethod();
}
问题是在specificMethod()
中,我希望调用_smth->methodForMemberB()
。
我可以看到以下方式:
在所有
specificMethods()
铸造?(在我看来,铸造就像是一艘救生艇,必须在非常复杂的情况下使用)模板时间?(不确定模板在这里是否合适)
设计是绝对错误的?
提前感谢。
问题是,当你使用/依赖Basic
来存储你的B
指针时,你正在失去信息,它不仅仅是一个A
实例。在这种情况下,您没有遵循(Liskov)继承原则!
有几种方法可以解决这个问题。模板是一种方法,但这取决于具体情况,在这种情况下,更"面向接口"的解决方案可能更合适。在这种情况下的问题是,您将B
存储在基类中,所以这是我们在这里要避免的。相反,使用抽象接口:
class Basic {
protected:
virtual shared_ptr<A> getPtr () = 0;
public:
// calls A/B/C->commonMethod();, uses getPtr ()
void commonMethod();
};
// Which works with B
class MoreSpecific : public Basic {
protected:
// Store and implement interface for base classes
shared_ptr<B> b_ptr;
shared_ptr<A> getPtr () {return b_ptr;}
public:
MoreSpecific(shared_ptr<B> b_ptr) : b_ptr(b_ptr);
// calls b->methodForMemberB();
void specificMethod();
};
如果你真的需要一个类来存储裸a ptr,你可以让这个类实现Basic
接口。总的教训是:没有数据成员的抽象接口是个好主意!
如果MoreSpecific
接口只对B
实例有效,则必须确保不将A
对象设置为Basic::_smth
。您可以使用基类模板
template<typename T>
class BasicBase {
protected:
shared_ptr<T> _smth;
public:
BasicBase (shared_ptr<T> a_ptr) : _smth(a_ptr);
void commonMethod();
}
typedef BasicBase <A> Basic;
// Which works with B only
class MoreSpecific : public Basic<B> {
public:
MoreSpecific(shared_ptr<B> b_ptr) : Basic(b_ptr);
// calls b->methodForMemberB();
void specificMethod();
}
相关文章:
- CLANG 编译器 说:变量"PTR"可能未初始化
- EASTL矢量<向量<int>>连续的
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 这是MSVC 2013中具有共享PTR的单例的正确实现吗?
- 对唯一 ptr 无效读取的引用向量
- C++ 类型转换基础 PTR 到派生 PTR 保存在引用类中
- 如何使用非类型参数传递模板化类的 Ref 或 Ptr