<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>冒号论坛 &#187; Tag: mixin - Recent Posts</title>
		<link>http://bbs.zhenghui.org/tags/mixin</link>
		<description>冒号论坛 &raquo; Tag: mixin - Recent Posts</description>
		<language>en-US</language>
		<pubDate>Wed, 08 Feb 2012 23:01:59 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://bbs.zhenghui.org/search.php</link>
		</textInput>
		<atom:link href="http://bbs.zhenghui.org/rss/tags/mixin" rel="self" type="application/rss+xml" />

		<item>
			<title>hui on "CRTP是怎么实现mixin的呢?"</title>
			<link>http://bbs.zhenghui.org/topic/crtp%e6%98%af%e6%80%8e%e4%b9%88%e5%ae%9e%e7%8e%b0mixin%e7%9a%84%e5%91%a2#post-252</link>
			<pubDate>Wed, 01 Dec 2010 15:27:01 +0000</pubDate>
			<dc:creator>hui</dc:creator>
			<guid isPermaLink="false">252@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;&#60;a href=&#34;http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern&#34; rel=&#34;nofollow&#34;&#62;CRTP（Curiously recurring template pattern）&#60;/a&#62;是 C++ 的一个惯用法，即一个类继承一个以该类为模板参数的实例化模板类。很拗口，用代码表示则清楚得多——&#60;br /&#62;
class derived : public base&#38;lt;derived&#38;gt;  （也可用struct）&#60;/p&#62;
&#60;p&#62;利用template的特殊性，CRTP可用来实现static polymorphism，避免虚函数的额外开销，但CRTP同时也可以用来实现mixin。看一个简单的例子：&#60;br /&#62;
#include &#38;lt;iostream&#38;gt;&#60;/p&#62;
&#60;p&#62;using namespace std;&#60;/p&#62;
&#60;p&#62;template &#38;lt;typename T&#38;gt;&#60;br /&#62;
class ObjectCounter&#60;br /&#62;
{&#60;br /&#62;
    public:&#60;br /&#62;
        ObjectCounter()&#60;br /&#62;
        {&#60;br /&#62;
            ++objCount;&#60;br /&#62;
        }&#60;/p&#62;
&#60;p&#62;        virtual ~ObjectCounter()&#60;br /&#62;
        {&#60;br /&#62;
            --objCount;&#60;br /&#62;
        }&#60;br /&#62;
        int countObjects()&#60;br /&#62;
        {&#60;br /&#62;
            return objCount;&#60;br /&#62;
        }&#60;br /&#62;
    private:&#60;br /&#62;
        static int objCount;&#60;br /&#62;
};&#60;/p&#62;
&#60;p&#62;template &#38;lt;typename T&#38;gt; int ObjectCounter&#38;lt;T&#38;gt;::objCount(0);&#60;/p&#62;
&#60;p&#62;class X : public ObjectCounter&#38;lt;X&#38;gt;  // ObjectCounter被“混入”类型X&#60;br /&#62;
{&#60;br /&#62;
    public:&#60;br /&#62;
        void method1();&#60;br /&#62;
        int method2();&#60;br /&#62;
        //...&#60;br /&#62;
};&#60;/p&#62;
&#60;p&#62;int main()&#60;br /&#62;
{&#60;br /&#62;
{&#60;br /&#62;
    X x1;&#60;br /&#62;
    cout &#38;lt;&#38;lt; x1.countObjects() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    X x2;&#60;br /&#62;
    cout &#38;lt;&#38;lt; x2.countObjects() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    X* x3= new X;&#60;br /&#62;
    cout &#38;lt;&#38;lt; x3-&#38;gt;countObjects() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    delete x3;&#60;br /&#62;
    cout &#38;lt;&#38;lt; x1.countObjects() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    {&#60;br /&#62;
        X a;&#60;br /&#62;
        cout &#38;lt;&#38;lt; a.countObjects() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    }&#60;br /&#62;
    cout &#38;lt;&#38;lt; x1.countObjects() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    return 0;&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;上面采用的是class Derived : public Mixin&#38;lt;Derived&#38;gt;&#60;br /&#62;
此外还有一种利用CRTP实现mixin的方式：template &#38;lt;typename Base&#38;gt; class Mixin : public Base&#60;br /&#62;
例如：&#60;br /&#62;
#include &#38;lt;iostream&#38;gt;&#60;/p&#62;
&#60;p&#62;using namespace std;&#60;/p&#62;
&#60;p&#62;template &#38;lt;typename T&#38;gt;&#60;br /&#62;
class CallCounter : public T   // CallCounter被“混入”类型T&#60;br /&#62;
{&#60;br /&#62;
    public:&#60;br /&#62;
        CallCounter() : callCount(0)&#60;br /&#62;
        {&#60;br /&#62;
        }&#60;/p&#62;
&#60;p&#62;        int countCalls()&#60;br /&#62;
        {&#60;br /&#62;
            return callCount;&#60;br /&#62;
        }&#60;/p&#62;
&#60;p&#62;        void call()&#60;br /&#62;
        {&#60;br /&#62;
            ++callCount;&#60;br /&#62;
            T::call();&#60;br /&#62;
        }&#60;/p&#62;
&#60;p&#62;    private:&#60;br /&#62;
        int callCount;&#60;br /&#62;
};&#60;/p&#62;
&#60;p&#62;class Y&#60;br /&#62;
{&#60;br /&#62;
    public:&#60;br /&#62;
        void call()&#60;br /&#62;
        {&#60;br /&#62;
            cout &#38;lt;&#38;lt; &#34;call...&#34; &#38;lt;&#38;lt; endl;&#60;br /&#62;
        }&#60;br /&#62;
};&#60;/p&#62;
&#60;p&#62;int main()&#60;br /&#62;
{&#60;br /&#62;
    CallCounter&#38;lt;Y&#38;gt; y;&#60;br /&#62;
    y.call();&#60;br /&#62;
    cout &#38;lt;&#38;lt; &#34;call#=&#34; &#38;lt;&#38;lt; y.countCalls() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    y.call();&#60;br /&#62;
    y.call();&#60;br /&#62;
    cout &#38;lt;&#38;lt; &#34;call#=&#34; &#38;lt;&#38;lt; y.countCalls() &#38;lt;&#38;lt; endl;&#60;br /&#62;
    return 0;&#60;br /&#62;
}&#60;/p&#62;
&#60;p&#62;更深入的例子可参见&#60;a href=&#34;http://www.cs.umass.edu/~yannis/practical-fmtd.pdf&#34; rel=&#34;nofollow&#34;&#62; Mixin-Based Programming in C++&#60;/a&#62;
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>Thomson on "CRTP是怎么实现mixin的呢?"</title>
			<link>http://bbs.zhenghui.org/topic/crtp%e6%98%af%e6%80%8e%e4%b9%88%e5%ae%9e%e7%8e%b0mixin%e7%9a%84%e5%91%a2#post-250</link>
			<pubDate>Wed, 01 Dec 2010 10:53:23 +0000</pubDate>
			<dc:creator>Thomson</dc:creator>
			<guid isPermaLink="false">250@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;我看到第多态的那章这么说,可是CRTP是c++实现static polymorphism 的, 怎么又和mixin联系起来了呢?
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>Todd on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-107</link>
			<pubDate>Wed, 05 May 2010 10:22:57 +0000</pubDate>
			<dc:creator>Todd</dc:creator>
			<guid isPermaLink="false">107@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;看到一篇相关文章：&#60;br /&#62;
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>hui on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-63</link>
			<pubDate>Sun, 21 Feb 2010 23:47:15 +0000</pubDate>
			<dc:creator>hui</dc:creator>
			<guid isPermaLink="false">63@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;&#38;gt;&#38;gt;noncopyable不是接口，但却达到了接口类似的特征表达效果，与C#中可序列化类的标记[Serializable]有异曲同工之妙。&#60;/p&#62;
&#60;p&#62;是的，书中p307提到的标记接口和属性导向式编程（@OP）正适合那些无法用接口直接表征的类型特性。这在Java和C#中比较常见，而在C++中除noncopyable这种特殊用法外并不多见，一个明显的原因是前二者对metadata有更强大的支持。&#60;/p&#62;
&#60;p&#62;&#38;gt;&#38;gt;接口是有主客关系的，类的这种行为&#34;特征&#34;不一定需要客户的存在。不知道这种表达“特征”而不涉及客户接口的方式就是mixin或者traits是否有关联？ &#60;/p&#62;
&#60;p&#62;这话恐怕不太准确。如果没有客户的存在，也就谈不上是否copyable了。而无论是mixin还是trait，都提供了一系列接口集合，它们与通常的抽象类型中interface的一个主要区别是除接口外还提供了实现；与abstract class的一个主要区别是摆脱了class hierarchy的桎梏。
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>hui on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-62</link>
			<pubDate>Sun, 21 Feb 2010 23:18:44 +0000</pubDate>
			<dc:creator>hui</dc:creator>
			<guid isPermaLink="false">62@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;&#38;gt;&#38;gt;noncopyable的原理从继承的角度看是通过基类对派生类产生约束而实现不可拷贝的效果的。我把这种方式称为“继承约束”，它与实现继承的“继承功能”和mixin的“混入功能”就显得有些不同。一个注重约束，一个注重功能。 &#60;/p&#62;
&#60;p&#62;你的这种说法有一定道理，但仅限于noncopyable这类特殊用法，其他的非公开继承（书中p241中提到的protected inheritance与private inheritance）还是注重功能而非约束的。当然，如果把约束看作一种特殊的功能（不妨称之为“负功能”？），它们又可以统一了。&#60;/p&#62;
&#60;p&#62;此外，书中提到noncopyable类似mixin的地方有一个关键处，即noncopyable类本身具有抽象性（因为一个单纯的noncopyable对象是毫无意义的——无论是语法上还是语义上），故可看作抽象类型（尽管不是严格语法意义上的抽象类型）。
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>Todd on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-61</link>
			<pubDate>Sun, 21 Feb 2010 21:30:30 +0000</pubDate>
			<dc:creator>Todd</dc:creator>
			<guid isPermaLink="false">61@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;noncopyable例子还有一个有趣的地方。一般来讲，一个类的功能特征是通过接口抽象（还包括数据抽象）来体现，但“不可拷贝”是无法对应到一个接口的！noncopyable不是接口，但却达到了接口类似的特征表达效果，与C#中可序列化类的标记[Serializable]有异曲同工之妙。&#60;/p&#62;
&#60;p&#62;我思考以后认为：接口是有主客关系的，类的这种行为&#34;特征&#34;不一定需要客户的存在。不知道这种表达“特征”而不涉及客户接口的方式就是mixin或者traits是否有关联？
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>Todd on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-60</link>
			<pubDate>Sun, 21 Feb 2010 21:06:19 +0000</pubDate>
			<dc:creator>Todd</dc:creator>
			<guid isPermaLink="false">60@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;书中的确讲到了，看的时候这部分没有留下很深的印象。&#60;/p&#62;
&#60;p&#62;p297讲“本质上看是一种类似mixin功能的抽象类型”。我认为这是一种另类继承的原因在于：noncopyable的原理从继承的角度看是通过基类对派生类产生约束而实现不可拷贝的效果的。我把这种方式称为“继承约束”，它与实现继承的“继承功能”和mixin的“混入功能”就显得有些不同。一个注重约束，一个注重功能。
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>hui on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-53</link>
			<pubDate>Sat, 20 Feb 2010 21:59:47 +0000</pubDate>
			<dc:creator>hui</dc:creator>
			<guid isPermaLink="false">53@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;你说的这种继承和boost::nocopyable书中分别在p241和p297中已经介绍过了，它们属于仅继承实现而不继承接口的继承。C++支持这种用法，但Java和C#不支持。
&#60;/p&#62;
</description>
		</item>
		<item>
			<title>Todd on "另类继承"</title>
			<link>http://bbs.zhenghui.org/topic/%e5%8f%a6%e7%b1%bb%e7%bb%a7%e6%89%bf#post-52</link>
			<pubDate>Sat, 20 Feb 2010 21:31:36 +0000</pubDate>
			<dc:creator>Todd</dc:creator>
			<guid isPermaLink="false">52@http://bbs.zhenghui.org/</guid>
			<description>&#60;p&#62;书中继承机制部分介绍了实现继承和接口继承，但感觉还有另一种继承的用法可以说的。比如boost::nocopyable就是利用了C++基类的私有拷贝构造函数防止派生类的拷贝构造。我觉得这类用法既不属于实现继承也不属于接口继承，只是利用了继承配合特定的语言特性达到目的。&#60;/p&#62;
&#60;p&#62;这也许已经不属于OOP理论范畴，而是与具体语言相关的一些技巧，所以我将这类用法归为实现继承、接口继承之外也另类继承。
&#60;/p&#62;
</description>
		</item>

	</channel>
</rss>

