为什么很多地方采用这样的设计?

蓝鹰 2013-10-21 09:47:43

class IBasic
{
public:
enum Type // 每个枚举值对应一个派生类
{
T_A,
T_B,
T_Unknown
};

virtual Type getType() const = 0;
};

class A: public IBasic
{
public:
virtual IBasic::Type getType() const
{
return IBasic::T_A;
}
};

class B: public IBasic
{
public:
virtual IBasic::Type getType() const
{
return IBasic::T_B;
}
};



我想这种写法大家肯定见过。但我想提出两个问题。
1.这样设计的好处在哪里?
2.如果添加新的派生类,就得修改基类中的枚举定义。有没有什么办法避免这样做?
我的做法是把IBasic::Type用派生类中声明的静态常量字符串代替。
...全文
263 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
MFC是个宝库呀,建议参考一下这是怎么实现RTTI的
nextseconds 2013-10-22
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
1.这样设计的好处在哪里? //这就是多态的使用,比如在一个函数内处理对象集合的数据遍历,既有A对象,也有B对象,以及可能的其它IBase派生类对象,那么你只要使用这样的代码 for (i=0;i<n;i++) { IBase* pi=col[i];//数组中保存的全部是基类指针 int t=pi->Type(); .... } 程序能自动的使用定义时的类型调用对应Type函数,你不用关心pi到底是什么类型定义产生的,这就是多态的媚力; 2.如果添加新的派生类,就得修改基类中的枚举定义。有没有什么办法避免这样做? //添加一个枚举工作是非常小的,使用字符串避免修改也是一个办法,但是对数据处理而言,枚举类型转二进制后是一个整形,我们知道,程序处理整形数据比处理字串数据方便快捷的多 浅见,仅供参考
赵4老师 2013-10-21
  • 打赏
  • 举报
回复
这个世界上唯一不变的就是变化。 请拥抱变化。 不然码农们早失业了,不是吗?
worldy 2013-10-21
  • 打赏
  • 举报
回复
晕,我也弄错了 class IBasic { public: enum Type // 每个枚举值对应一个派生类 { T_A, T_B, T_Unknown }; virtual Type getType() const = 0; }; class A: public IBasic { public: //virtual IBasic::Type getType() const,怎么会是IBase::? virtual Type getType() const { return IBasic::T_A; } }; class B: public IBasic { public: virtual Type getType() const { return IBasic::T_B; } };
worldy 2013-10-21
  • 打赏
  • 举报
回复
引用 楼主 blackeagleX 的回复:

class IBasic
{
public:
    enum Type   // 每个枚举值对应一个派生类
    {
        T_A,
        T_B,
        T_Unknown
    };

    virtual Type getType() const = 0;
};

class A: public IBasic
{
public:
    virtual IBasic::Type getType() const
    {
        return IBasic::T_A;
    }
};

class B: public IBasic
{
public:
    virtual IBasic::Type getType() const
    {
        return IBasic::T_B;
    }
};

我想这种写法大家肯定见过。但我想提出两个问题。 1.这样设计的好处在哪里? 2.如果添加新的派生类,就得修改基类中的枚举定义。有没有什么办法避免这样做? 我的做法是把IBasic::Type用派生类中声明的静态常量字符串代替。
LZ你这个定义有问题吧,难怪高手都说没见过 class IBasic { public: enum Type // 每个枚举值对应一个派生类 { T_A, T_B, T_Unknown }; virtual Type getType() const = 0; }; class A: public IBasic { public: //virtual IBasic::Type getType() const,怎么会是IBase::? virtual A::Type getType() const { return IBasic::T_A; } }; class B: public IBasic { public: virtual B::Type getType() const { return IBasic::T_B; } };
worldy 2013-10-21
  • 打赏
  • 举报
回复
1.这样设计的好处在哪里? //这就是多态的使用,比如在一个函数内处理对象集合的数据遍历,既有A对象,也有B对象,以及可能的其它IBase派生类对象,那么你只要使用这样的代码 for (i=0;i<n;i++) { IBase* pi=col[i];//数组中保存的全部是基类指针 int t=pi->Type(); .... } 程序能自动的使用定义时的类型调用对应Type函数,你不用关心pi到底是什么类型定义产生的,这就是多态的媚力; 2.如果添加新的派生类,就得修改基类中的枚举定义。有没有什么办法避免这样做? //添加一个枚举工作是非常小的,使用字符串避免修改也是一个办法,但是对数据处理而言,枚举类型转二进制后是一个整形,我们知道,程序处理整形数据比处理字串数据方便快捷的多 浅见,仅供参考
menzi11 2013-10-21
  • 打赏
  • 举报
回复
这样应该是为了某种动态转型吧,比如一个函数接收父类指针后,通过这个函数能够快速 确定子类的类型然后child* p=(child*)basePtr. 自打有了dynamic_cast,这技巧我觉得就不用需要了....
  • 打赏
  • 举报
回复
难道这就是传说的面向接口的编程? 如果添加新的派生类,就得修改基类中的枚举定义 ---- 为什么要修改?
秃头披风侠 2013-10-21
  • 打赏
  • 举报
回复
同2楼也没见过 不过看写法,应该是想在运行时判断类型,能够得到具体的子类类型. 其他的解决方法当然有,你说的是一种,不过我觉得不太好.因为从代码片段看, 后续的用法可能是根据返回值new子类类型或者进行类型转换之类的操作, 可能会使用switch之类的操作, 这样显然还是枚举要好些, 而且使用字符串的话占用空间也会上升. 不过具体还要看怎么用, 如果只是单纯的想知道实例化的子类是什么, 那么用字符串也无妨.
蓝鹰 2013-10-21
  • 打赏
  • 举报
回复
引用 1 楼 ouyh12345 的回复:
很多地方?我没看见过
不知道你用过Ogre没
ouyh12345 2013-10-21
  • 打赏
  • 举报
回复
很多地方?我没看见过
unituniverse2 2013-10-21
  • 打赏
  • 举报
回复
自定义模拟RTTI机制的
worldy 2013-10-21
  • 打赏
  • 举报
回复
没有什么大不了,编译后枚举值只是一个数值,你完全可以在派生类中定义新的常量,再说了,你举的例子,都是通过成员函数返回类型值,直接return 5之类的也行,不定义枚举类型也没什么问题
蓝鹰 2013-10-21
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
1.这样设计的好处在哪里? //这就是多态的使用,比如在一个函数内处理对象集合的数据遍历,既有A对象,也有B对象,以及可能的其它IBase派生类对象,那么你只要使用这样的代码 for (i=0;i<n;i++) { IBase* pi=col[i];//数组中保存的全部是基类指针 int t=pi->Type(); .... } 程序能自动的使用定义时的类型调用对应Type函数,你不用关心pi到底是什么类型定义产生的,这就是多态的媚力; 2.如果添加新的派生类,就得修改基类中的枚举定义。有没有什么办法避免这样做? //添加一个枚举工作是非常小的,使用字符串避免修改也是一个办法,但是对数据处理而言,枚举类型转二进制后是一个整形,我们知道,程序处理整形数据比处理字串数据方便快捷的多 浅见,仅供参考
是的,我也不喜欢用字符串。而且,修改一个枚举的工作在能拿到源码的情况下的确没什么。 但是如果这个IBasic是我们发布给客户的类呢。这样客户根本无法做扩展了。或者说,就算这个类是内部使用,增加一个派生类会导致基类的重新编译。 c++ 的编译速度大家也是知道的
蓝鹰 2013-10-21
  • 打赏
  • 举报
回复
引用 10 楼 blackeagleX 的回复:
[quote=引用 8 楼 worldy 的回复:] 晕,我也弄错了 class IBasic { public: enum Type // 每个枚举值对应一个派生类 { T_A, T_B, T_Unknown }; virtual Type getType() const = 0; }; class A: public IBasic { public: //virtual IBasic::Type getType() const,怎么会是IBase::? virtual Type getType() const { return IBasic::T_A; } }; class B: public IBasic { public: virtual Type getType() const { return IBasic::T_B; } };
引用 8 楼 worldy 的回复:
晕,我也弄错了 class IBasic { public: enum Type // 每个枚举值对应一个派生类 { T_A, T_B, T_Unknown }; virtual Type getType() const = 0; }; class A: public IBasic { public: //virtual IBasic::Type getType() const,怎么会是IBase::? virtual Type getType() const { return IBasic::T_A; } }; class B: public IBasic { public: virtual Type getType() const { return IBasic::T_B; } };
可能是多了个作用域吧[/quote] 但这不是问题的重点
qq120848369 2013-10-21
  • 打赏
  • 举报
回复
这种设计是很糟糕的, 相当于反射.
蓝鹰 2013-10-21
  • 打赏
  • 举报
回复
引用 8 楼 worldy 的回复:
晕,我也弄错了 class IBasic { public: enum Type // 每个枚举值对应一个派生类 { T_A, T_B, T_Unknown }; virtual Type getType() const = 0; }; class A: public IBasic { public: //virtual IBasic::Type getType() const,怎么会是IBase::? virtual Type getType() const { return IBasic::T_A; } }; class B: public IBasic { public: virtual Type getType() const { return IBasic::T_B; } };
引用 8 楼 worldy 的回复:
晕,我也弄错了 class IBasic { public: enum Type // 每个枚举值对应一个派生类 { T_A, T_B, T_Unknown }; virtual Type getType() const = 0; }; class A: public IBasic { public: //virtual IBasic::Type getType() const,怎么会是IBase::? virtual Type getType() const { return IBasic::T_A; } }; class B: public IBasic { public: virtual Type getType() const { return IBasic::T_B; } };
可能是多了个作用域吧

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧