減少編譯時間:pointer to implementation(Impl設計模式)
PIMPL(Private Implementation 或 Pointer to Implementation)是通過一個私有的成員指標,將指標所指向的類的內部實現資料進行隱藏。
1)降低模組的耦合。因為隱藏了類的實現,被隱藏的類相當於原類不可見,對隱藏的類進行修改,不需要重新編譯原類。
2)降低編譯依賴,提高編譯速度。指標的大小為(32位)或8(64位),x.h發生變化,指標大小卻不會改變,檔案c.h(包含x.h)也不需要重編譯。
3)介面與實現分離,提高介面的穩定性。
1. #define的保護
所有標頭檔案都應該使用#define 防止標頭檔案被多重包含(multiple inclusion)
當是:<PROJECT>_<PATH>_<FILE>_H_
為保證唯一性,標頭檔案的命名應基於其所在專案原始碼樹的全路徑。例如,專案foo 中的頭
檔案foo/src/bar/baz.h 按如下方式保護:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_
2. 標頭檔案依賴
使用前置宣告(forward declarations)儘量減少.h 檔案中#include 的數量。
當一個頭檔案被包含的同時也引入了一項新的依賴(dependency),只要該標頭檔案被修改,
程式碼就要重新編譯。如果你的標頭檔案包含了其他標頭檔案,這些標頭檔案的任何改變也將導致那
些包含了你的標頭檔案的程式碼重新編譯。因此,我們寧可儘量少包含標頭檔案,尤其是那些包含
在其他標頭檔案中的。
使用前置宣告可以顯著減少需要包含的標頭檔案數量。舉例說明:標頭檔案中用到類File,但不
需要訪問File 的宣告,則標頭檔案中只需前置宣告class File;無需#include
"file/base/file.h"。
在標頭檔案如何做到使用類Foo 而無需訪問類的定義?
1) 將資料成員型別宣告為Foo *或Foo &;
2) 引數、返回值型別為Foo 的函式只是宣告(但不定義實現);
3) 靜態資料成員的型別可以被宣告為Foo,因為靜態資料成員的定義在類定義之外。
另一方面,如果你的類是Foo 的子類,或者含有型別為Foo 的非靜態資料成員,則必須為
之包含標頭檔案。
有時,使用指標成員(pointer members,如果是scoped_ptr 更好)替代物件成員(object
members)的確更有意義。然而,這樣的做法會降低程式碼可讀性及執行效率。如果僅僅為
了少包含標頭檔案,還是不要這樣替代的好。
當然,.cc 檔案無論如何都需要所使用類的定義部分,自然也就會包含若干標頭檔案。
譯者注:能依賴宣告的就不要依賴定義。
以上是Google中C++程式設計規範的前兩條要求。第一條相信大家都知道。第二條就是我要說的問題了。
這裡我用VS2012解釋下這個事情。要減少編譯的目的就是要減少#include;
那我們先定義這樣兩個類:
- #pragma once
- class A
- {
- public:
- A(void);
- ~A(void);
- };
- #pragma once
- #include "A.h"
- class B
- {
-
public:
- B(void);
- ~B(void);
- private:
- A a;
- };
可以看到這是很簡單的組合類的情況。B類中有個A的物件。下面我們生成一下。
這時候A,B第一次編譯成功
接下來我們修改物件A,在物件A中增加一個私有成員i,B不變;
- #pragma once
- class A
- {
- public:
- A(void);
- ~A(void);
- private:
- int i;
- };
這時候再生成一次,可以看到如下情況
可以看到A編譯後。編譯器發現B中匯入了A.h然後又編譯了一次B。
在工程量比較小的時候這麼做是沒關係的。但當你編譯一次程式碼需要1分鐘2分鐘的時候。我們頻繁的修改原始碼然後編譯你會崩潰的是不是?
所以前置宣告是一個可以選擇的解決方案。
B的程式碼只要做如下修改,取消匯入A.h在B.h中宣告class A;
- #pragma once
- class A;
- class B
- {
- public:
- B(void);
- ~B(void);
- private
- A* a;
- };
我們同樣在A沒修改之前做一次編譯。
同樣我們在A中加入私有成員後再編譯一次。
可以看到這裡只編譯了A.cpp檔案。
相關推薦
減少編譯時間:pointer to implementation(Impl設計模式)
PIMPL(Private Implementation 或 Pointer to Implementation)是通過一個私有的成員指標,將指標所指向的類的內部實現資料進行隱藏。 1)降低模組的耦合。因為隱藏了類的實現,被隱藏的類相當於原類不可見,對隱藏的類進行修改
設計模式--Pimpl(pointer to implementation 指向實現的指標)
#include "autotimer.h" #include <iostream> #if _WIN32 #include <windows.h> #else #include <sys/time.h> #endif class AutoTimer::Imple {
設計模式1:Simple Factory Pattern(簡單工廠模式)
工廠模式專門負責將大量有共同介面的類例項化。工廠模式可以動態決定將哪一個類例項化,不必事先知道每次要例項化哪一個類。工廠模式有以下幾種形態: 簡單工廠(Simple Factory)模式 工廠方法(Factory Method)模式 抽象工廠(Abstract Factor
java 之 策略模式(大話設計模式)
src 客戶端代碼 div strategy ring 溫故 bre str disco 溫故而知新,每次讀設計模式都會有不同的體驗,堅持每天一個設計模式,直到熟練運用設計模式。 策略模式定義了很多完成相同工作的算法,但實現不同,它可以以相同的方式調用所有的算法,減少了算法
java 之 外觀模式(大話設計模式)
希望 重要 .com cad ima out 流程 mon nic 外觀設計模式,很多人都已經使用過,只是不知其名,一般一個很nice的系統,模塊化做的都很不錯,這樣如果新來一個業務,只需要把各個模塊組裝起來就可以滿足新的業務, 從程序的角度來說,就是我們只需要開一個類,
java 之 抽象工廠模式(大話設計模式)
out 簡單 ges 關系 logs 只需要 切換 ima .get 看了幾次抽象工廠模式,每次查看都需要重新理解一次,可能是涉及的類和接口比較多,所以比較難縷清的關系吧!在筆者看來,我們還是要吸取其思想而不是生搬硬套。 來看下類圖: 大話設計模式-類圖 看類圖已經很亂了
Command模式(命令設計模式)
Command?? 把方法的呼叫用一個類的例項來承載,要管理工作的歷史記錄,建立這些方法執行的命令的集合,只需管理這些例項的集合即可,而且還可以隨時再次執行過去的命令,或是將多個過去的命令整合為一個新命令並執行。稱之為Command設計模式 那裡合適使用: Command有時也被稱為事件(event
jQuery 版本購物車(融入設計模式)
jQuery 版本購物車(融入設計模式) 1. 介紹 1.1 功能 顯示購物列表、加入購物車、從購物車刪除 1.2 用到的設計模式 工廠模式 $('XXX'),建立商品 單例模式 購物車
Composite模式(組合設計模式)
Composite 設計模式? 在計算機的檔案系統中,有“資料夾”的概念(在有些作業系統(Linux作業系統)中,也稱為“目錄”)。資料夾裡面既可以放入檔案,也可以放入其他資料夾(子資料夾)。在子資料夾中,一樣地既可以放入檔案,也可以放入子資料夾。可以說,資料夾是形成了一種容器結構、遞迴結構。 結構模式:能
State模式(狀態設計模式)
State??? State模式中,我們用類來表示狀態。以類來表示狀態後,我們就能通過切換類來方便地改變物件的狀態。當需要增加新的狀態時,如何修改程式碼這個問題也會很明確。 直接用狀態代替硬編碼 依賴於狀態的處理,來執行具體的操作 理清職責 實現功能: ·有一個金庫 ·金庫與警報中心相連 ·金庫裡有
SpringMVC(前端設計模式)簡介
一、提供一個入口,讓所有的請求都進行 / ,然後再分配給對應的頁面,這就是前端設計模式(front)@WebServlet("/") 不過濾 .jsp public class DemoServlet extends HttpServlet{ @Override protected
設計模式之Factory(工廠設計模式)
工廠模式是我們很常用的模式了,著名的spring框架就使用了工廠模式。 為什麼說工廠模式是最常用的,因為工廠模式就相當於建立物件的new。工廠模式就是用來建立物件的 在PatternsInJava 書中把工廠模式主要分為:工廠方法與抽象工廠,當然這本書在舉例
介面的定義及使用(工廠設計模式)
為了讓使用者能得到他們想要的東西,使用者只用輸入他們能夠輸入東西,而不用輸入程式碼來得到他們想要的東西。下面寫一個簡單的例子:interface Fruit{ public void eart();}class Apple implements Fruit{ public v
Java第三十四天(MVC設計模式)
MVC設計模式 JSP的開發模式 三層架構&MVC練習 學生資訊管理系統 資料庫準備 CREATE DATABASE
Linux時間子系統之八:動態時鐘框架(CONFIG_NO_HZ、tickless)
sleep file rup linux時間 load 曾經 大致 獲取 conf 在前面章節的討論中,我們一直基於一個假設:Linux中的時鐘事件都是由一個周期時鐘提供,不管系統中的clock_event_device是工作於周期觸發模式,還是工作於單觸發模式,也不管定時
UVa 817:According to Bartjens(DFS)
題目連結 https://vjudge.net/problem/UVA-817 題意:輸入一個以等號結尾。前面只包含數字的表示式,插入一些加號、減號和乘號,使得運算結果等於2000.表示式裡的整數不能有前導零(例如,0100和000都是非法的),運算子都是二元的
Best Time to Buy and Sell Stock II 最佳時間買入賣出股票(多次買賣)@LeetCode
題目:最佳時間買入賣出股票:你有一個數組儲存了股票在第i天的價錢,現在你可以進行多次買入賣出,但同一時間你手上只能保持一個股票,如何賺的最多思路:貪心法,本題和前面的Best Time to Buy and Sell Stock 不同在於,本題可以多次買賣股票,從而累積賺取所
jdk8和tomcat7出現jsp無法編譯問題:Unable to compile class for JSP
org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: 1 in the generated java file The type jav