Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+的使用和缺点+;指定类的模板参数';基类? 背景_C++_Templates_Multiple Inheritance_Variadic Templates - Fatal编程技术网

C++ C+的使用和缺点+;指定类的模板参数';基类? 背景

C++ C+的使用和缺点+;指定类的模板参数';基类? 背景,c++,templates,multiple-inheritance,variadic-templates,C++,Templates,Multiple Inheritance,Variadic Templates,最近,我一直在思考如何设计一个特定的软件,在某一点上,我制作了以下内容: 模板 Foo类:公共虚拟混合。。。{ /* ... */ }; 我的想法是能够根据用户的需要使用附加属性或行为来扩充基本类。假设一个应用程序需要使用带有标识号的Foos。也许其他应用程序需要能够使用颜色谈论Foos。可以通过添加以下类来满足这些需求: 类HasID{ int m_id=-1; 公众: int getID(){return m_id;} void assignID(int id){m_id=id;} };

最近,我一直在思考如何设计一个特定的软件,在某一点上,我制作了以下内容:

模板
Foo类:公共虚拟混合。。。{
/* ... */
};
我的想法是能够根据用户的需要使用附加属性或行为来扩充基本类。假设一个应用程序需要使用带有标识号的
Foo
s。也许其他应用程序需要能够使用颜色谈论
Foo
s。可以通过添加以下类来满足这些需求:

类HasID{ int m_id=-1; 公众: int getID(){return m_id;} void assignID(int id){m_id=id;} }; 类HasColor{ 公众: int color=0; }; 问题 关于此代码,我的两个问题如下:

  • 使用这样的模板有哪些用途和缺点
  • 这个特殊的图案有名字吗
  • 附加示例代码 下面是一个额外的示例,展示了可以打印扩展类的对象的详细信息

    打印功能:

    //默认打印库
    模板
    void printBase(std::ostream&out,Base&x){}
    //HasID的printBase
    模板
    void printBase(标准::ostream&out、HasID&x){
    
    out让我回答第二部分:是的,这个模式有一个名称:

    关于此代码,我的两个问题如下:

    这个特殊的图案有名字吗

    使用这样的模板有哪些用途和缺点

    CRTP是“奇怪的重复模板模式”,有时也称为“mixin”

    当网络知道这种模式/习惯用法时,我们真的想在这里再次讨论缺点吗?讨论得够多了:-)

    本文指出:

    CRTP技术的最大缺点是构造函数不是继承的。这意味着,如果在实现类中使用初始化构造函数,则每个扩展都必须有一个适当的初始化构造函数。这会导致扩展受到更多限制,因此用处不大

    对于c++14来说,这不再是事实,你有很好的机会用可变模板和基类的构造函数调用链杀死这个参数。继承和委派构造函数也将有助于实现这一目的


    与所有模板一样,您必须记住,每个实例化都是一种新类型,可能会导致可执行文件中出现大量代码重复。我经常使用这种模式,并接受成本。另一种方法是手工制作可执行文件大小不小于的代码。您必须支付所需的费用。

    Hmm,该页上的示例使用来消除vtables,并在定义类的位置指定基类。另一方面,在我的示例中,基类是在定义对象的位置指定的。是否允许用户定义混入的基类?在这种情况下,当两个基类发生影响时,可能会出现问题每个人的行为。例如,
    Foo
    可能意味着你的Foo对象应该充满地外生命形式,而
    Foo
    只是意味着现在是咖啡时间…;)@W.F.应该允许用户定义基类,尽管大多数情况下用户在“用户定义”中我确实看到了应该相互影响的基的问题,这不是我所预期的。我所想象的用例主要是添加附加属性,几乎没有行为。但它真的是CRTP吗?CRTP以
    classX:Base{}的形式表现出来这与我所描述的不同,它(如果不考虑变量部分)的形式是
    模板类X:B{};