Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300977
  • 博文数量: 47
  • 博客积分: 1411
  • 博客等级: 上尉
  • 技术积分: 500
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-23 09:10
文章分类

全部博文(47)

文章存档

2009年(3)

2008年(4)

2007年(14)

2006年(26)

我的朋友

分类: C/C++

2006-02-23 21:45:12

      由于benchmark的抽象逻辑很简单,但复杂而且易变的部分在其底层的I/O解析部分。所以设计起来有点尴尬:太抽象,本身逻辑很清晰,但会加重下层逻辑的负担,换一个协议时,下层逻辑需要动的部分太多;减少抽象,逻辑上就比较模糊,比如抽象在I/O解析部分,则对于每一个协议都可以很快的实现,但是造成benchmark可能需要不停的适应新协议的变化,不够通用。以下时碰到的几个问题:

1)静态成员变量。

static修饰的成员变量,即静态成员。一般用来解决所有实例共享数据的问题,或者说所有类共有的属性、特征。但是有个很矛盾的事实是,他使用起来很丑陋。如果共享的是一个常量,那还可以,如果是一个对象或者对象引用,就麻烦了,你得在一个合适的(共享对象创建后)地方给静态变量赋值,并且赋值语句可能在整个代码流程中显的比较丑陋,怪异,比如:在一个函数中突然来一个:
void foo() {
     ClassA *a = new ClassA;
     a.Init();
..............
     ClassB::ptr_A = a;
..........
}
我是觉得很丑陋。有一个解决方法,但只适用于在全局范围内,共享的实例只有一个。在ClassA的构造中添加: ClassB::ptr_A = this; 其实逻辑上也不好,ClassB关A什么事情呢?为什么A要在自己的构造中给B好处呢?
我觉得静态成员变量要慎用。

2)自我管理类

如果我们不想引入一个类来专门管理一些数量在变化中,并且管理比较分散类实例时。可以构建该类自己的管理机制,我称之为垃圾回收、再利用机制。这种类型的类有个比较奇怪的特性:动态分配实例可能再类外部,或者类内部。而释放实例的动作由实例内部触发。一般释放时我们不会去使用delete this这样古怪的语言。那么既然实例自己不能使用delete,就把自己放入一个静态的类中的垃圾回收器。最后由类外部的程序来释放垃圾。当然这样的好处还有分配实例时,可以直接从垃圾堆里取一个出来,避免了动态的开销。这样的类声明的例子:
class CManageMyself
{
public:
 .....................
public:
          void DestroyAll(); // call by outer code
private:
          void GarbageCollect(CManageMyself *mm); // push mm to garbage collector
          CManageMyself *GetInstance() {
                   CManageMyself *mm;
                   if ( there's no garbages ) {
                          mm = new CManageMyself;
                          return mm;
                   }
                   // get a garbage from collector
                   return garbages.pop();
          }
}

3)低耦合

当然这个是面向对象设计的原则。尽量保持类于类之间低耦合性

4)多个类声明中互相声明对方类指针

这个情况的出现,已经一定程度上违背3条。不过没办法。必须注意的是,在互相引用声明中,最好只在一个类声明文件中包含另一个类的头文件,而后者的头文件里,不要包含前者的头文件,只要简单的在类声明前声明一下另一个类的类型。如:
// classA.h
#include "classB.h"
class classA {
      classB *pb;
}
 
// classB.h
class classA;
class classB {
      classA *pa;
}
否则编译会通不过,道理很简单。千万别帮这个方法用在声明对方类上面来,只能是指针。否则编译器不能得知类实例的大小,编译无法通过。

5)限定模板参数类型

有时候我们需要限定一下模板参数的类型。当然最好是让编译器来检查。最easy的方法是,在模板类中调用改限定类型的某些特定方法,或者变量。实在不行就利用boost吧:
 // declarative way, overloadable!
template
void foo(T t, typename boost::enable_if< boost::is_base_of,int >::type = 0)
{
// do your business here!
}

// imperative way, can't be used in overload resolution!
template
void foo1(T t)
{
BOOST_STATIC_ASSERT( (boost::is_base_of::value) );

// do your business here!
}
参考:
阅读(2090) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~