在同一个函数中调用不同时间的不同类

时间:2009-06-29 17:18:24

标签: c++ class

我无法想象一种方法来调用具有通用性的函数。我有一个代码,必须在不同的时刻在两个不同的类中调用一个函数。

我有A和B课程,我可以访问一次或其他时间。或者我访问A或I访问B.不是两个都在同一类型。

我已编写此程序代码,但我无法想象如何执行此操作。或者,如果这有利于性能或编码。我只想消除C类,但我不知道如何。

有什么想法吗?

class MyClass  
 {  
    public:  
       MyClass() {} //contructor padrão, não deve ser utilizado isoladamente  

        virtual int a() = 0;  
        virtual int b() = 0;  

        int c()
        {
            return b();
        }

 };  

class A : public MyClass  
{  
    public:  
        int a() { return 1; }  
        int b() { return 1; }  
        int d() { return 1; }  
};  

class B : public MyClass  
{  
    public:  
        int a() { return 1; }  
        int b() { return 1; }  
        int e() { return 1; }  
};  

class C 
{  
public:  
    A ca;  
    B cb;  

    enum TIPO { A, B };  
    TIPO Tipo;  

    C(TIPO tipo) { Tipo = tipo; }  

    int a()  
    {  
        switch(Tipo)  
        {  
        case A:  
            return ca.a();  
            break;  
        case B:  
            return  cb.b();  
            break;  
        default:  
            break;  
        }  
    }  

};  


void main()  
{  
    C c(C::B);  
    c.a();   
    return;  
}  

5 个答案:

答案 0 :(得分:2)

如果我理解正确,你试图消除成员(ca,cb),并调用适当的基类方法。

如果是这种情况,可以使用以下方式完成:

switch(Tipo) {
case A:
    return A::a();
case B:
    return B::a();
}

但是,我建议您重新审视您的设计。通常,这样的情况通常可以通过重新思考/重新设计类设计来处理,以便有一个定义a()的基类或接口,而不是创建一个具有2个基类的具体类,创建两个特定的,从单个基类派生的具体类。这里不需要多重继承。 (尤其如此,因为您知道施工时的类型。)

答案 1 :(得分:0)

首先,通过继承或合成来确定您的A和B类是否属于C.现在你正在做两件事,这既使你的代码膨胀,也让它变得混乱。

如果你继续进行继承,那么你还有另外一个问题:类似命名的重写方法,Deadly Diamond of Death.多重继承的主要原因,如果你没有听到,是邪恶的。除非没有其他方法可以完成工作,否则请避免使用它。

如果你选择作曲(我的推荐),那么在我看来你的“不在同一时间”的说明就变得没必要了。您没有访问相同的数据,因此不存在竞争条件。如果你(由于一些不正当的理由)决定访问相同的内存空间,那么你需要了解多线程,其实现将因你开发的每个平台而有所不同。

答案 2 :(得分:0)

好吧,我想你希望C :: a()根据C的“类型”或“模式”来调用A :: a()或B :: b()。首先,没有必要让C继承A和B.

class C
{
  private:
    A ca;  
    B cb; 

    enum TIPO { A, B };  
    TIPO Tipo;

  public:
    SetTipo(TIPO tipo) { Tipo = tipo; }

    // ..
};

void main()  
{  
    C c(C::B);  // Start with mode B and call B::b()
    c.a();
    c.SetTipo(C::A); // Now I'm in mode A .. call A::a()
    c.a();   
    return;  
}  

这假设C真的应该拥有A的一个实例和B的一个实例,我不确定这是否是你想要的。你的问题没有说明是否是这种情况。

干杯

答案 3 :(得分:0)

当你写'A'和'B'时,你实际上并不需要C类。通过将您的成员函数声明为“virtual”,您将使用运行时多态,这将导致调用“正确”函数:

void foo (MyClass & mc) {
  mc.a ();
}

int main () {
  A a;
  B b;

  foo (a);  // 'mc.a()' will call 'A::a'
  foo (b);  // 'mc.a()' will call 'B::a'
}

还有其他原因需要从C继承?

答案 4 :(得分:0)

这个问题非常不清楚。我对这个问题有另一种解释,并附上答案。

解释:给出:

 class C {
 public:
  int a();
  int b();
 };

您想要调用方法a()或方法b(),可在运行时选择。解决方案:成员函数指针。

成员函数指针类似于常规C函数指针,除了它适用于类中的方法,并且其类型签名包括它所调用的类的名称。以下是如何使用我刚刚给出的类:

  typedef int (C::*SELECT_FUNC)(void);

这是成员函数指针的声明。它类似于常规C函数指针的声明,并添加了类名。现在我们可以分配它:

 SELECT_FUNC ptr = &C::a;
 SELECT_FUNC other_ptr = &C::b;

致电:

 C item;
 C *item_ptr;

 int rv = item.*ptr();
 int rv2 = item_ptr->*other_ptr;

这种语法很时髦。将“*”视为“取消引用”。我们正在取消引用成员函数指针以获取METHOD,此时我们可以以正常方式调用该方法。

关于这一点很酷的事情是:如果方法是虚拟的,它甚至都不重要。您可以将虚方法或非虚方法分配给成员函数指针。如果通过函数指针调用方法并且该方法恰好是虚拟的,那么您将获得一个真正的虚拟调用(即,如果声明函数指针指向基类方法,但是您使用派生类实例“this”,然后将调用派生类方法,就像正常的虚拟调用一样。)

我会认真考虑你的要求。你的问题不是很好,这使我相信你不了解自己真正想要实现的目标。一旦理解了想要实现的目标,那么类层次结构或成员函数指针(或两者)可能是解决问题的最佳选择。