这是将抽象类与OO方法一起使用的正确方法吗?

Is this a correct approach of using abstract classes with an OO approach?

本文关键字:方法 一起 抽象类 OO      更新时间:2023-10-16

假设我们有 2 个类 A 和 B。两者都是超类 C 的子类。现在让我们假设 C 定义了一个方法 areYouA((,这是一个询问对象是否是 A 类对象的方法。

因此,在 c++ 中,可能的代码是:

C object1 = A()
C object2 = B()
if (object1.areYouA()==true){//crazy code here regarding if it's an A object}
if (object2.areYouA()==false){//crazy code here regarding if it's a B object}

从 OO POV 中,向 B 和 C 类添加一个方法以询问它们各自的对象是否属于 A 类是否正确???如果不正确,那么还有什么方法可以解决这个问题呢????我的目标很明显,我需要 2 个类 A 和 B,在某些时候我有部分二进制数据可能是 A 类或 B 类,而且一个对象最初是 A 类,当它变满时,它的结构需要改变,还有一些行为, 因此成为 B 类的对象。因此,我的方法是将抽象类视为父类,最初声明一个 C 对象但存储一个 A 对象,然后在它发生变化时存储一个 B 对象。这还有别的吗,比如模式???

附加信息:

我想我对此不是很清楚。假设我想将来自 A 对象的信息存储在文件 1 中,将来自 B 对象的信息存储在文件 2 中。如果使用其母类作为接口,那么我如何判断它是 A 对象还是 B 对象以存储在各自的文件中?我是否应该为每个对象的文件名添加贡品,因为它们也属于它们???这意味着如果我需要更改文件名,那么每个对象也需要更改。

正确的方法是使用虚函数来实现多态行为:

struct C
{
    virtual void do_crazy_stuff() { } // (see text below)
    virtual ~C() { }                  // always have a virtual d'tor for polymorphic bases
};
struct A : C
{
    virtual void do_crazy_stuff() { /* your crazy code for A */ }
};
struct B : C
{
    virtual void do_crazy_stuff() { /* your crazy code for B */ }
};

现在您可以在任何地方使用相同的界面:

void process_data(C & x)  // <-- Note: take argument by reference!!
{
    x.do_crazy_stuff();
}

这适用于派生自C类型的任何对象:

int main()
{
    A x;
    B y;
    process_data(x);  // calls x.A::do_crazy_stuff
    process_data(y);  // calls x.B::do_crazy_stuff
}

如果你愿意,你甚至可以将基函数C::do_crazy_stuff声明为纯虚拟函数;这使得基类抽象(因此它不能被实例化(。

首先,

C object1 = A();
C object2 = B();

对对象进行切片。它们不再是A型或B型,而是C

你可以为此使用指针:

C* object1 = new A();
C* object2 = new B();

尽管C指针,但它们分别指向AB的实例。

第二,你的方法是错误的。您似乎没有利用多态性。如果您有在类之间共享的功能,则应在 C 中实现。如果它发生了变化,您应该有virtual方法。

关于对象类型的知识通常至少是一种代码气味。只需使用多态性即可更改行为。尽管如果确实有必要,正确的方法是使用dynamic_cast

C* object1 = new A();
A* pA = dynamic_cast<A*>(object1);

如果object1不指向类型为 A 的对象,则将NULL pA

在我看来,这是一个设计问题,你必须更好地分析你的问题。为什么需要知道对象的类型?为什么你不在 A 和 B 类中实现接口方法,它将对二进制数据做你需要的任何操作?查看访客设计模式,以获取如何以这种方式实现它的图像。