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

时间:2021-07-08 23:57:03

I just cannot imaginate a way to do a call to a function with genericity. I have a code which a have to call a function in two different classes in different moments.

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

I have A and B classes which I can access one time or other time. Or I access A or I access B. Not both in the same type.

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

I have code this program but I just cannot imagine how to do this. Or if this is good for performance or codding. I just want to eliminate the C class but I don't know how.

我有这个程序的代码,但我无法想象如何做到这一点。或者,如果这有利于性能或编码。我只想消除C类,但我不知道如何。

Any idea?

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 个解决方案

#1


As you've written 'A' and 'B', you don't actually need the C class. By declaring your member functions "virtual" you are using run time polymorphism and this will result in the "correct" functions being called:

当你写'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'
}

Is there some other reason that you need to inherit from C?

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

#2


If I understand you correctly, you are trying to eliminate the members (ca,cb), and just call the appropriate base class method.

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

If that's the case, it can be done by using:

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

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

However, I would recommend revisiting your design. Typically, situations like this can often be handled by rethinking/reworking the class design so that there is a single base class or interface which defines a(), and instead of creating one concrete class with 2 base classes, create one of two specific, concrete classes derived from a single base class. There is no need for multiple inheritance here. (This is especially true since you know the type at construction time.)

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

#3


First of all, decide if your A and B classes will belong to C by inheritance or by composition. Right now you're doing both, which is both bloating your code and making it confusing.

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

If you do go for inheritance, then you have another problem: similarly named overridden methods, a prime cause for the Deadly Diamond of Death. Multiple inheritance, in case you haven't heard, is evil. Avoid it unless there is no other way to get the job done.

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

If you go with composition (my recommendation), then it seems to me that your specification of "not at the same time" becomes unnecessary. You're not accessing the same data, so there's no possibility of a race condition. And if you are (for some ungodly reason) determined to access the same memory space, then you'll need to brush up on multithreading, the implementation of which will differ with each platform you develop on.

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

#4


Ok, I guess you want C::a() to call A::a() or B::b() depending on what "type" or "mode" C has. First of all there is no need to let C inherit A and B.

好吧,我想你希望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;  
}  

This assumes that C really should own one instance of A and one instance of B and I'm not sure if that's what you want. Your question didn't state if that's the case or not.

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

Cheers

#5


This question is very unclear. I have another interpretation of the question, along with an answer.

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

Interpretation: given:

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

You want to call either method a() or method b(), selectable at runtime. Solution: member function pointers.

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

A member function pointer is like a regular C function pointer, except that it applies to a method in a class, and its type signature includes the name of the class it's invoked on. Here's how to use one with the class I've just given:

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

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

This is the declaration of the member function pointer. It is similar to the declaration of a regular C function pointer, with the addition of a class name. Now we can assign it:

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

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

And to call:

并致电:

 C item;
 C *item_ptr;

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

This syntax is funky. Think of the "*" as "dereference". We are dereferencing the member function pointer to get a METHOD, at which point we can invoke the method in what is otherwise the normal way.

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

The cool thing about this is: it doesn't even matter if the methods are virtual or not. You can assign either a virtual method or a non-virtual method to a member function pointer. If you call a method through a function pointer and the method happens to be virtual, then you'll get a true virtual call (i.e. if the function pointer is declared to point to a base class method, but you use a derived class instance for "this", then the derived class method will be called, just as it is for a normal virtual call.)

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

I would think through your requirements carefully. Your question is not well asked, which leads me to believe that you do not understand yourself what you really want to achieve. Once you understand what you want to achieve, then either a class hierarchy or member function pointers (or both) may be the best choice to solve your problem.

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

#1


As you've written 'A' and 'B', you don't actually need the C class. By declaring your member functions "virtual" you are using run time polymorphism and this will result in the "correct" functions being called:

当你写'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'
}

Is there some other reason that you need to inherit from C?

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

#2


If I understand you correctly, you are trying to eliminate the members (ca,cb), and just call the appropriate base class method.

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

If that's the case, it can be done by using:

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

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

However, I would recommend revisiting your design. Typically, situations like this can often be handled by rethinking/reworking the class design so that there is a single base class or interface which defines a(), and instead of creating one concrete class with 2 base classes, create one of two specific, concrete classes derived from a single base class. There is no need for multiple inheritance here. (This is especially true since you know the type at construction time.)

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

#3


First of all, decide if your A and B classes will belong to C by inheritance or by composition. Right now you're doing both, which is both bloating your code and making it confusing.

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

If you do go for inheritance, then you have another problem: similarly named overridden methods, a prime cause for the Deadly Diamond of Death. Multiple inheritance, in case you haven't heard, is evil. Avoid it unless there is no other way to get the job done.

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

If you go with composition (my recommendation), then it seems to me that your specification of "not at the same time" becomes unnecessary. You're not accessing the same data, so there's no possibility of a race condition. And if you are (for some ungodly reason) determined to access the same memory space, then you'll need to brush up on multithreading, the implementation of which will differ with each platform you develop on.

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

#4


Ok, I guess you want C::a() to call A::a() or B::b() depending on what "type" or "mode" C has. First of all there is no need to let C inherit A and B.

好吧,我想你希望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;  
}  

This assumes that C really should own one instance of A and one instance of B and I'm not sure if that's what you want. Your question didn't state if that's the case or not.

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

Cheers

#5


This question is very unclear. I have another interpretation of the question, along with an answer.

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

Interpretation: given:

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

You want to call either method a() or method b(), selectable at runtime. Solution: member function pointers.

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

A member function pointer is like a regular C function pointer, except that it applies to a method in a class, and its type signature includes the name of the class it's invoked on. Here's how to use one with the class I've just given:

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

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

This is the declaration of the member function pointer. It is similar to the declaration of a regular C function pointer, with the addition of a class name. Now we can assign it:

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

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

And to call:

并致电:

 C item;
 C *item_ptr;

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

This syntax is funky. Think of the "*" as "dereference". We are dereferencing the member function pointer to get a METHOD, at which point we can invoke the method in what is otherwise the normal way.

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

The cool thing about this is: it doesn't even matter if the methods are virtual or not. You can assign either a virtual method or a non-virtual method to a member function pointer. If you call a method through a function pointer and the method happens to be virtual, then you'll get a true virtual call (i.e. if the function pointer is declared to point to a base class method, but you use a derived class instance for "this", then the derived class method will be called, just as it is for a normal virtual call.)

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

I would think through your requirements carefully. Your question is not well asked, which leads me to believe that you do not understand yourself what you really want to achieve. Once you understand what you want to achieve, then either a class hierarchy or member function pointers (or both) may be the best choice to solve your problem.

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