App*_*ood 7 c++ oop templates specialization
假设您有一个班级,他们的工作就是连接到远程服务器.我想抽象这个类来提供两个版本,一个通过UDP连接,另一个通过TCP连接.我想构建最精简的运行时代码,而不是使用多态,我正在考虑模板.这是我想象的,但我不确定这是最好的方法:
class udp {};
class tcp {};
template<class T,typename X>
class service
{
private:
  // Make this private so this non specialized version can't be used
   service();
};
template<typename X>
class service<udp, X>
{
private:
   udp _udp;
   X _x;
};
template<typename X>
class service<tcp, X>
{
private:
   tcp _tcp;
   X _x;
};
因此最终的好处是T的通用性仍然可用,但设置UDP或TCP连接所需的非常不同的代码已经过专门化.我想你可以将它们放在一个类中,或者提供另一个类,它遵循一些纯虚拟接口来设置网络连接,比如IConnectionManager.
但这确实留下了通用T的代码问题,现在必须在两个专用版本中编写和维护,它们最终都是相同的.如何最好地解决这个问题?我有一种感觉,我认为这一切都错了.
Joh*_*itb 12
最好使用传输协议的策略来完成此操作:
template<typename Transport>
class service : Transport {
public:
    typedef Transport transport_type;
    // common code
    void do_something() { 
        this->send(....);
    }
};
class tcp {
public:
    void send(....) {
    }
};
class udp {
public:
    void send(....) {
    }
};
typedef service<tcp> service_tcp;
typedef service<udp> service_udp;
请注意,这也是多态的.它被称为编译时多态.将策略放入基类将受益于Empty-Base-Class-Optimization.也就是说,您的基类不需要占用任何空间.将策略作为成员具有另一个缺点,即您总是必须将内容委托给该成员,这可能会随着时间的推移而变得烦人." Modern C++ Design "一书深入描述了这种模式.
理想情况下,传输协议不需要知道有关它上面的协议的任何信息.但是如果由于某种原因你必须得到一些关于它的信息,你可以使用crtp模式wiki:
template<template<typename Service> class Transport>
class service : Transport<service> {
    // since we derive privately, make the transport layer a friend of us, 
    // so that it can cast its this pointer down to us. 
    friend class Transport<service>;
public:
    typedef Transport<service> transport_type;
    // common code
    void do_something() { 
        this->send(....);
    }
};
template<typename Service>
class tcp {
public:
    void send(....) {
    }
};
template<typename Service>
class udp {
public:
    void send(....) {
    }
};
typedef service<tcp> service_tcp;
typedef service<udp> service_udp;
您不必将模板放入标题中.如果明确地实例化它们,您将获得更快的编译时间,因为必须包含更少的代码.把它放到service.cpp中:
template class service<tcp>;
template class service<udp>;
现在,使用服务的代码不需要知道模板的服务代码,因为该代码已经生成到service.cpp的目标文件中.
我会使用奇怪的重复模板模式,又名五点棕榈爆炸亚历山大技术:
template <typename Underlying>
class Transmit
{
public:
   void send(...)
   {
      _U.send(...)
   };
private:
    Underlying _U;
};
class Tcp
{
public:
   void send(...) {};
};
class Udp
{
public:
   void send(...) {};
};
可能会有更多的模板参数和子类,但您明白了,您也可以使用静态方法。
顺便说一句,模板代码通常更高效,但也更大。
| 归档时间: | 
 | 
| 查看次数: | 3865 次 | 
| 最近记录: |