发新话题
打印

c++ 模板的哲学

c++ 模板的哲学

假如要实现,一个类型:表示狮身人面的动物
基于类的实现是这样:
复制内容到剪贴板
代码:
class 抽象人_C{
抽象人_C(头,身子):头(头),身子(身子){}
void 跑()
{
this->身子.跑();
}
void 吃()
{
this->头.吃();
}

头_base 头;
身子_base 身子;
}

struct 头_base
{
virtual void 吃() = 0;
}

struct 身子_base
{
virtual void 跑() = 0;
}

struct 人头 : 头_base
{
void 吃()
{
使用刀叉筷子吃;
}
}
struct 狮子头 : 头_base
{
void 吃()
{
嘴脚并用, 撕着吃
}
}
struct 人身 : 身子_base
{
void 跑()
{
撒开两脚跑;
}
}

struct 狮身 : 身子_base
{
void 跑()
{
四脚跑;
}
}

抽象人_C  a(人头, 人身); // 一个人类实例
抽象人_C  b(狮头, 狮身); // 一个狮子实例
抽象人_C  c(人头, 狮身); // 一个狮身人面实例
基于模板的实现是这样:
复制内容到剪贴板
代码:
template<typename 头trait, 身子trait> class 抽象人_T{
static  void 跑()
     {
        身子trait::跑();
     }
static void 吃()
{
   头traits::吃();
}
}
struct 人头
{
static void 吃()
{
  使用刀叉筷子吃;
}

}
struct 狮子头
{
static void 吃()
{
  嘴脚并用,撕着吃
}
}
struct 人身
{
static void 跑()
{
  撒开两脚跑;
}

}

struct 狮身
{
static void 跑()
{
  四脚跑;
}
}
抽象人_T<人头,人身> a; // 一个人类实例
抽象人_T<狮头, 狮身> b; // 一个狮子实例
抽象人_T<人头, 狮身> c; // 一个狮身人面实例

TOP

1.怎么实现不同功能?
  模板通过传入类型参数,编译出相应的类,再使用传入类型的静态方法来实现,
  类是通过传入不同的对象实例,调用相应的实例方法来实现

2.接口约定方法?
  即怎么知道某个对象,有什么方法,比如,吃,跑这些方法怎么给出?模板是编译时匹配,如果匹配不到,就报错,类方法是通过定义虚类,即接口类的方法来保证。

3.有没有共同的基类?
  模板类实现,没有共同的基类,比如,以下是两个完全不同的类型:
  抽象人_T<人头,人身> a; // 一个人类实例
  抽象人_T<狮头, 狮身> b;
  vector<抽象人_T > two={a,b}; //错误,实际上根本不存在抽象人_T,这样的类,抽象人_T<人头,人身>,下划线,左右尖括号,逗号,都应看作类名一部分

  类实现,有共同基类,以下正确:
  抽象人_c a(人头,人身); // 一个人类实例
  抽象人_c b(狮头, 狮身);
  vector<抽象人_T > two={a,b}; // 正确,存在类,抽象人_T

4.用模板实现,是否导致执行程序变大?
  一定啊,不同参数类型,编译出不同完全不同的代码,程序变大是必须的,比如,要实现既支持http,又支持https的web服务器,如果按模板实现,必须编译出两个完全不同的类。

5.哪个更具代码重用性? 我选择模板,拿cpu和gpu(显卡芯片)的关系来说,如果cpu内含gpu,那么这种芯片我们就理解为通过类方法来构造的,cpu和gpu关系紧密,无法拆解,如果是独显的情况,那么可以拆解,显然,独显可以提高gpu的重用性。


6.能否使用多态机制?
  模板无法实现多态,运行时就得按类型运行不同代码,而用多态可能使代码更简洁,更优雅,如:
  模板实现的 web服务器启动代码:
  httpserver<http> http_ server;
  httpserver<https> https_ server;

  http_server.init_port(8080);
  http_server.listen();
  http_server.run();


  https_server.init_port(8443);
  https_server.listen();
  https_server.run();

  类实现的 web服务器启动代码:
  void start(httpserver &server,int port)
  {
    server.init_port(port);
    server.listen();
    server.run();
  }
  httpserver http_server(HTTP);
  httpserver https_ server (HTTPS);

  start(http_server,8080);
  start(https_server,8443);

TOP

发新话题