通用var c ++

时间:2009-06-26 14:04:24

标签: c++ generics var

我想创建一个泛型var,它可以来自一个类或另一个类。

在这段代码示例中,我希望var aa是通用的,所以在我的代码中我可以访问A类或B类代码。

但是必须是全球性的。

你能帮帮我吗?

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

    static MyClass* getInstance()
    {
        static MyClass *instance = 0;
        if (!instance) instance = new MyClass();
            return instance;
    }
};

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

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

template <class TAIT> class AIT
{
public:
    static TAIT& Instance()
    {
        static TAIT instance;
        return instance;
    }
};

AIT aa;

void main()
{
    aa.Instance().a(); // or
    aa.Instance().b(); // aa could be class
                       // A or class B. So I could access
                       // function a or function b (not at same
                       // time, of course)

    return;
}

6 个答案:

答案 0 :(得分:7)

简短回答:

C ++模板为您提供编译时通用性,而非运行时通用性。

模板本身在程序中不存在(即具体的二进制可执行文件)。只有在通过显式或隐式指定其参数进行实例化时,它们才会以生成的代码结束。

所以,这不会声明变量:

AIT aa;

这声明了一个变量:

AIT<A> aa;

如果需要运行时通用性,则必须使用运行时调度机制:

  • 使用开关盒手动完成。
  • 或者更好地使用公共基类的内置继承+一些虚方法。

答案 1 :(得分:2)

如果我理解正确的话,我认为你只需要正确地声明aa,然后就可以了:

AIT<A> aa;
aa.Instance().a();

AIT<B> bb;
bb.Instance().b();

如果这不是您的意思,请编辑您的问题并说明您要做的事情。

答案 2 :(得分:1)

在基类中声明一个纯虚拟,在派生类中重载它。

class MyClass {
public:
   virtual int a() = 0;
};

class DerivedA : public MyClass {
public:
   virtual int a() { return 1; }
};

两个派生类都有一个具有相同名称的方法,您将根据对象类型自动解决调用哪个方法。您必须重写GetInstance()方法的创建部分才能知道要创建的类实例。

答案 3 :(得分:0)

如果您不希望在getInstance方法中调用构造函数,则可以将其设为私有。 e.g。

class MyClass
{
private:
    MyClass() {} //contructor padrão, não deve ser utilizado isoladamente
public:
    static MyClass* getInstance()
    {
        static MyClass *instance = 0;
        if (!instance) instance = new MyClass();
            return instance;
    }
};

现在

MyClass* a = new MyClass();

因为你的构造函数是私有的,会导致编译错误

答案 4 :(得分:0)

这是解决这个问题的好方法吗?

  

class MyClass {       上市:          MyClass(){} //contructorpadrão,nãodeveser utilizado   isoladamente             virtual int a()= 0; virtual int b()= 0;

  int c()         {           return b();         }

   static MyClass* getInstance()
   {
      static MyClass *instance = 0; //          if (!instance) instance
     

= new MyClass();             返回实例;          }};

     

A类:公共MyClass {public:         int a(){return 1; } int b(){   返回1; } int d(){return 1; }};

     

B类:公共MyClass {public:         int a(){return 1; } int b(){   返回1; } int e(){return 1; }};

     

C类:公众A,公众B {public:     一个ca; B cb;

     

enum TIPO {A,B}; TIPO Tipo;

     

C(TIPO tipo){Tipo = tipo; }

     

int a(){switch(Tipo){case   答:返回ca.a();打破;案件   B:返回cb.b();打破;         默认值:break; }}

     

};

     

void main(){// MyClass * A =   MyClass的::的getInstance(); // MyClass * B.   = MyClass :: getInstance();

     

C c(C :: B); C.A();
  // aa.Instance()。a();   // aa.Instance()。b();

     

返回; }

答案 5 :(得分:0)

这绝对是令人讨厌的,但也许这里的解决方案是使用void指针。在C和C ++中,声明为void *的指针被定义为没有类型。您可以传递此指针,然后将其转换为您希望的任何数据类型的指针。显然,非常小心地确保变量实际上是正确的类型是至关重要的,但如果您正在设计一个您不知道返回类型的接口,这可能很有用。以下是接口类外观的示例:

class InterfaceClass {
  public:
     virtual void* someInterface() = 0;
}

然后,您可以创建另一个实现该界面的类,并执行您想要的任何有趣的事情:

class DerivedClass: public InterfaceClass {
  public:
     virtual void* someInterface() {
        //do some stuff
        return (void*) somePointer;

}

只要您了解要做的任何代码,您就可以传回所需的任何类型的指针。如果您在Google上搜索无效指针,那么还有更多信息。小心。