﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-mirguest-随笔分类-C++</title><link>http://www.cppblog.com/mirguest/category/15953.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 29 Jun 2012 15:33:09 GMT</lastBuildDate><pubDate>Fri, 29 Jun 2012 15:33:09 GMT</pubDate><ttl>60</ttl><item><title>关于隐藏实现代码</title><link>http://www.cppblog.com/mirguest/archive/2012/06/23/179871.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sat, 23 Jun 2012 08:14:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/06/23/179871.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/179871.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/06/23/179871.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/179871.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/179871.html</trackback:ping><description><![CDATA[<h1>关于隐藏实现代码</h1>
<p>C++ 一直没有学明白，对于一些问题，一直也没有解决。
今天尝试解决的问题，来源于微软如何把它的库实现隐藏起来。</p>
<p>之前的想法是，不管定义何种类和方法，总应该在头文件中出现声明，
从而，一些private的方法和变量我们也应该可以推断出来。
但是，事实并不是这样，很多时候，看到的只是public的。</p>
<p>而从理论上来说，应该将实现与接口分离。像微软提供的头文件，
的确已经定义好了固定的接口。而这样，它们只需要再提供类库，
我们就可以用了。</p>

<div class="section" id="id2">
<h1>定义接口</h1>
<p>首先，定义一个称为 MyClass 的类，为了方便，我创建了一个目录，
专门用于存放编译我们自己类库的代码。</p>
<p>MyClass.h 的代码非常简单：</p>
<pre class="literal-block">#ifndef MyClass_H
#define MyClass_H
class MyClass {
public:
void run();
};
#endif
</pre>
<p>这个之后会暴露给用户。但我们先不进行实现。</p>
</div>
<div class="section" id="id3">
<h1>实现隐藏代码</h1>
<p>下面，做的是真正的工作，即我们不需要给用户看的。</p>
<p>定义 PrivateMyClass.h 和 PrivateMyClass.cpp 。</p>
<p>PrivateMyClass.h 内容很简单：</p>
<pre class="literal-block">#ifndef PrivateMyClass_H
#define PrivateMyClass_H
class PrivateMyClass {
public:
void canrun();
};
#endif
</pre>
<p>PrivateMyClass.cpp 也简单：</p>
<pre class="literal-block">#include &lt;iostream&gt;
#include "PrivateMyClass.h"
void PrivateMyClass::canrun() {
std::cout &lt;&lt; "Begin Can RUN?" &lt;&lt; std::endl;
std::cout &lt;&lt; "End Can RUN?" &lt;&lt; std::endl;
}
</pre>
</div>
<div class="section" id="id4">
<h1>封装隐藏代码</h1>
<p>然后，我们在 MyClass 的实现中，调用 PrivateMyClass 。</p>
<p>MyClass.cpp 内容：</p>
<pre class="literal-block">#include &lt;iostream&gt;
#include "MyClass.h"
#include "PrivateMyClass.h"
void MyClass::run() {
std::cout &lt;&lt; "Begin RUN" &lt;&lt; std::endl;
PrivateMyClass pmc;
pmc.canrun();
std::cout &lt;&lt; "End RUN" &lt;&lt; std::endl;
}
</pre>
</div>
<div class="section" id="id5">
<h1>编译生成动态库</h1>
<p>有了这些，就可以编译出动态库了，写一个 Makefile ：</p>
<pre class="literal-block">lib:MyClass.o PrivateMyClass.o
&nbsp;&nbsp;&nbsp;g++ -g -shared -o libresult.so MyClass.o PrivateMyClass.o
MyClass.o:MyClass.cpp MyClass.h
&nbsp;&nbsp;&nbsp;g++ -fPIC -Wall -g -c MyClass.cpp
PrivateMyClass.o:PrivateMyClass.cpp PrivateMyClass.h
&nbsp;&nbsp;&nbsp;g++ -fPIC -Wall -g -c PrivateMyClass.cpp
</pre>
</div>
<div class="section" id="id6">
<h1>给出头文件和动态库</h1>
<p>这样，我们就可把 MyClass.h 和 libresult.so 给用户了。
我放到public的目录下。</p>
</div>
<div class="section" id="id7">
<h1>测试</h1>
<p>为了确保正常运行，写代码测试一下：</p>
<pre class="literal-block">#include "MyClass.h"
int main() {
MyClass mc;
mc.run();
}
</pre>
<p>然后是Makefile：</p>
<pre class="literal-block">all:exe
&nbsp;&nbsp;&nbsp;LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH ./result
test1:exe
&nbsp;&nbsp;&nbsp;LD_LIBRARY_PATH=../private/:$LD_LIBRARY_PATH ./result
test2:exe
&nbsp;&nbsp;&nbsp;LD_LIBRARY_PATH=../private-v2/:$LD_LIBRARY_PATH ./result
exe:TestClass.o
&nbsp;&nbsp;&nbsp;g++ -o result TestClass.o -L. -lresult
TestClass.o:TestClass.cpp
&nbsp;&nbsp;&nbsp;g++ -c TestClass.cpp
</pre>
<p>这个里面，包含了另外的一个测试：即库更新后，
我是否可以不重新编译用户代码。</p>
<p>结论是，可以不用重新编译用户代码。</p>
 </div><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><img src ="http://www.cppblog.com/mirguest/aggbug/179871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-06-23 16:14 <a href="http://www.cppblog.com/mirguest/archive/2012/06/23/179871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>