gpt4 book ai didi

c++ - 当它被称为 shared_ptr 时调用派生类方法

转载 作者:行者123 更新时间:2023-11-30 01:58:50 24 4
gpt4 key购买 nike

我坚信这是一个非常常见的面向对象问题,但谷歌搜索没有给我答案。我希望有人能指出正确的方法来摆脱我的僵局。我尝试了解和使用标准技术,避免重新发明轮子。

这里简单介绍一下:

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()

我可以看到以下几种方式:

  1. 在所有 specificMethods() 中转换? (在我看来,类型转换是一种救生艇,必须在非常复杂的情况下使用)

  2. 是时候制作模板了吗? (不确定模板在这里是否合适)

  3. 设计绝对错误?

提前谢谢你。

最佳答案

问题是,当您使用/依赖 Basic 来存储您的 B 指针时,您正在丢失它不仅仅是一个 A 的信息 实例。在这种情况下,您没有遵循 (Liskov) 继承原则!

有几种解决方法。模板是一种方式,但这取决于具体情况,在这种情况下,更“面向界面”的解决方案可能是合适的。这种情况下的问题是您将 B 存储在基类中,因此我们将在此处避免这种情况。相反,使用抽象接口(interface):

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 接口(interface)。要吸取的一般教训是:没有数据成员的抽象接口(interface)是个好主意!

关于c++ - 当它被称为 shared_ptr<Basic> 时调用派生类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16773959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com