2012-02-04 121 views
0

定义对象类型我有这样的基本设置:C++通过枚举

enum{ 
    BASE, 
    PRIMITIVE, 
    ... 
}; 

class IUnknown{ 
public: 
    bool inline is(int type){return inv_type == type;} 
private: 
    enum {inv_type = BASE}; 
}; 

class Primitive: public IUnkown{ 
private: 
    enum {inv_type = PRIMITIVE}; 
}; 

我的问题是,我会希望能够调用是一个原始的实例,并把它返回true时类型等于在Primitive类中声明的枚举值。

我发现的唯一的解决方法是申报“”功能为虚拟和在每个子类中的副本,但我不知道是否有可能以某种方式重新定义枚举,并有在IUnkown功能自己采取从那里

+0

我怀疑你没有正确地将多态性应用于你的问题。你不应该以这种情况开始。虚拟绑定将确定每个定义的虚拟方法的对象行为,而不需要通过is()检查对象类型。 – 2012-02-04 17:06:18

+0

我同意罗伯特,似乎你正在尝试手动实现动态多态。 – enobayram 2012-02-04 17:13:43

+1

您可能希望避免使用名称并研究“IUnknown”的实际用法,它是使用中的一大块多态代码的基础。 – ssube 2012-02-04 17:22:46

回答

1

你可以让你的IUnknown类中定义一个受保护的构造(然后就必须从每一个派生类的称呼)。它将采用一个枚举值并存储它。然后将存储的值与is()方法进行比较。

如果你不喜欢这一点,宁愿添加一个虚拟的是()方法的IUnknown,但不希望在每一个派生类中定义它,你可以这样做:

template <int Tinv_type> 
class IUnknownT : public IUnknown{ 
public: 
    virtual bool is(int type){return inv_type == type;} 
protected: 
    enum {inv_type = Tinv_type}; 
}; 

class Primitive: public IUnknownT<PRIMITIVE>{ 
}; 
+0

我想你错过了我写IUnknownT这个从IUnknown派生的事实(除了is()方法是纯虚拟的,它本身不会改变OP的版本)。 – 2012-02-04 17:24:00

+0

啊,是的,我确实想念那个。 – 2012-02-04 17:24:49

+0

谢谢,这工作像一个魅力 – 2012-02-04 17:46:05

1

enum S中的价值,因为他们是可接受值的一个enum变量只是列出了不占用存储空间。您必须拥有一些运行时存储才能实现虚拟功能,以实际处理对象的运行时类型。我只想用一个int或东西:

enum{ 
    BASE, 
    PRIMITIVE, 
    ... 
}; 

class IUnknown{ 
public: 
    bool is(int type) const {return inv_type == type;} 

protected: 
    IUnknown(int type) : inv_type(type) { } 

private: 
    const int inv_type; 
}; 

class Primitive: public IUnkown{ 
private: 
    Primitive() : IUnknown(PRIMITIVE) { } 
}; 
+0

(它也应该是'const'。) – 2012-02-04 17:19:08

+0

@KerrekSB嗯,忘了'const'吧,谢谢。我是一个健忘的人:) – 2012-02-04 17:19:47

0

为什么不全部使用字符串而不是枚举。

const char * baseStr = "base"; 
const char * derived1Str = "derived1"; 
const char * derived2Str = "derived2"; 

class base 
{ 
public: 
    virtual bool is(const char * str) 
    { 
     return strcmp(baseStr, str) ? false : true; 
    } 
}; 

class derived1 : public base 
{ 
public: 
    bool is(const char * str) 
    { 
     if (strcmp(derived1Str, str)) 
      return base::iA(str); 

     return true; 
    } 
}; 

class derived2 : public derived1 
{ 
public: 
    bool is(const char * str) 
    { 
     if (strcmp(derived2Str, str)) 
      return derived1::is(str); 

     return true; 
    } 
}; 

这样做的好处,这

base * b = new derived2(); 
bool is = b->isA(baseStr); 

istrue