这是使用抽象类和OO方法的正确方法吗?

时间:2012-05-06 16:13:28

标签: c++ design-patterns subclass superclass

假设我们有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类???如果它不正确,那么可能是另一种方法呢????我的目标是显而易见的,我有两个类A和B,我需要,在某些时候我有部分二进制数据可以是A类或B类,也是一个对象最初是A类,因为它得到完整,它的结构需要改变,也需要改变它的一些行为,因此成为B类的一个对象。所以我的方法是将抽象类视为父类,并且最初声明一个C对象但是存储一个A对象,然后在它更改时存储一个B对象。 还有另一个approch,就像一个模式???

附加信息:

我想我对此并不十分清楚。假设我想存储来自file1中的A对象的信息,以及来自file2中的B对象的信息。如果使用它的母类作为接口,那么我如何判断它是一个A对象还是一个B对象来存储在各自的文件中?我应该为每个对象添加一个属性的文件名,它们也属于???这意味着如果我需要更改文件的名称,那么每个对象也需要更改。

3 个答案:

答案 0 :(得分:4)

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

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声明为纯虚拟;这使基类 abstract (因此无法实例化)。

答案 1 :(得分:4)

首先,

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

切片对象。它们不再是AB类型,而是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);
如果pA未指向NULL类型的对象,则

object1将为A

答案 2 :(得分:1)

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

相关问题