青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

CMake使用

cmake學習(一)靜態(tài)庫與動態(tài)庫構(gòu)建

(.so)共享庫,shared object:節(jié)省空間,在運行時去連接,如果執(zhí)行機器上沒有這些庫文件就不能執(zhí)行。
(.a)靜態(tài)庫,archive:靜態(tài)庫和程序化為一體,不會分開。
通過 ldd命令可以查看一個可執(zhí)行程序所依賴的的共享庫。
使用環(huán)境變量LD_LIBRARY_DIRECTORY可以指定共享庫位置


一、編譯共享庫:
ADD_LIBRARY(hello SHARED ${SHARED_LIBRARY})

二、添加靜態(tài)庫:
ADD_LIBRARY(hello STATIC ${STATIC_LIBRARY})
因為默認規(guī)則是不能有相同名字的共享庫與靜態(tài)庫,所以當生成靜態(tài)庫的時候(so后綴),共享庫會被刪除,因為只能允許一個名字存在,相同名字的會被替代(hello),所以需要通過SET_TARGET_PROPERTIES()來解決這個問題,例子:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
cmake在構(gòu)建一個target的時候,會刪除之前生成的target,一樣是通過設置SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)來達到目的
三、動態(tài)庫的版本號:
同樣是通過SET_TARGET_PROPERTIES()來設置
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION:動態(tài)庫版本
SOVERSION:API版本
最后生成的結(jié)果是:
libhello.so.1.2
libhello.so.1->libhello.so.1.2
libhello.so->libhello.so.1
四、安裝:
INSTALL(TARGETS hello hello_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
INSTALL(TARGETS hello.h
DESTINATION include/hello)
其他常用的屬性 PERMISSIONS:設置權限;RATTERN:設置正則表達式


Summary:
ADD_LIBRARY():添加一個庫,共享庫,靜態(tài)庫,模塊
SET_TARGET_PROPERTIES():設置輸出名稱,版本號,解決相同target被刪除的問題
GET_TARGET_PROEERTIES():與SET功能相對

cmake學習(二)常用變量和常用環(huán)境變量
一、變量的引用方式是使用“${}”,在IF中,不需要使用這種方式,直接使用變量名即可
二、自定義變量使用SET(OBJ_NAME xxxx),使用時${OBJ_NAME}
三、cmake的常用變量:
CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR:
這三個變量內(nèi)容一致,如果是內(nèi)部編譯,就指的是工程的頂級目錄,如果是外部編譯,指的就是工程編譯發(fā)生的目錄。
CMAKE_SOURCE_DIR,PROJECT_SOURCE_DIR,_SOURCE_DIR:
這三個變量內(nèi)容一致,都指的是工程的頂級目錄。
CMAKE_CURRENT_BINARY_DIR:外部編譯時,指的是target目錄,內(nèi)部編譯時,指的是頂級目錄
CMAKE_CURRENT_SOURCE_DIR:CMakeList.txt所在的目錄
CMAKE_CURRENT_LIST_DIR:CMakeList.txt的完整路徑
CMAKE_CURRENT_LIST_LINE:當前所在的行
CMAKE_MODULE_PATH:如果工程復雜,可能需要編寫一些cmake模塊,這里通過SET指定這個變量
LIBRARY_OUTPUT_DIR,BINARY_OUTPUT_DIR:庫和可執(zhí)行的最終存放目錄
PROJECT_NAME:你猜~~

 

四、cmake中調(diào)用環(huán)境變量
1.Using $ENV{NAME} : invoke system environment varible.
We can use "SET(ENV{NAME} value)" as well. note that the "ENV" without "$".
2.CMAKE_INCLUDE_CURRENT_DIR equal to INCLUDE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})


五、其他的內(nèi)置變量
1.BUILD_SHARED_LIBS:set the default value when using ADD_LIBRARY()
2.CMAKE_C_FLAGS: set compiler for c language
2.CMAKE_CXX_FLAGS: set compiler for c++ language


六、區(qū)分debug和release
在工程目錄下,cmake -DCMAKE__BUILD_TYPE=DEBUG(RELEASE),再執(zhí)行make


七、指定編譯32bit或64bit程序
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")

cmake學習(三)常用指令

一、基本指令:
INCLUDE_DIRECTORIES(${includedir}) #-I。
LINK_DIRECTORIES(${libdir}) #-L
TARGET_LINK_LIBRARIES(helloworld ${linkflags}) #-l
ADD_DEFINITIONS(${cflags}) #-D
 
1、ADD_DEFINATIONS:向C/CPP添加宏定義,相當于gcc中的-D,參數(shù)之間用空格分割
2、ADD_DEPENDICIES(target_name, depend_name):定義target對其他target的依賴關系
3、AUX_SOURCE_DIRECTORY(dir VARIBLE):把目錄下的所有源文件保存在變量中,基本用來創(chuàng)建源文件列表
4、ADD_EXECUTABLE:指定目錄,生成執(zhí)行文件
5、EXEC_PROGRAM:外部調(diào)用指令,可移執(zhí)行任何外部命令,后面加參數(shù),例子如下:
EXEC_PROGERAM(ls ARGS"*.c" OUTPUT_VARIBLE LS_OUTPUT RETURN_VALUE LS_RVALUE)
IF(not LS_RVALUE)
MESSAGE(STATUS "xxx")
ENDIF(not LS_RVAULE)
PS.這里執(zhí)行l(wèi)s *.c指令,執(zhí)行成功的話,返回0。
6、FILE指令:
FILE(WRITE file_name "content")
FILE(APPEND file_name "content")
FILE(READ file_name varible)
FILE(WRITE file_name "content")
7、FIND_系列指令:
LIBRARY( name path):
FIND_LIBRARY(Xorg X11 /usr/lib64)
IF(not Xorg)
MESSAGE(STATUS "no Xorg")
ENDIF(not Xorg)
FILE( name path)
PATH( name path)
PROGRAM( name path)
PACKAGE( [major.minor][QUIET][NO MODULE][[REQUIRED][COMPONTS][componts....]])
最后一條,用來調(diào)用放在CMAKE_MODULE_PATH下的Find.cmake模塊,也可以自定義Find模塊
首先通過SET(CMAKE_MODULE_PATH /home/...)來指定位置

8、控制指令:
IF(expression),ELSE(expression),ENDIF(expression)
express舉例:
否定:空,0,N,NO,OFF,F(xiàn)ALSE,NOTFOUND或_NOTFOUND
肯定:COMMAND cmd,EXISTS dir/file,variable MARCHES regex等等等等還有很多~~~隨用隨查吧


cmake學習(四)模塊的使用和自定義模塊

FIND_PACKAGE
每一個模塊都會產(chǎn)生如下變量
_FOUND
_INCLUDE_DIR
_LIBRARY or _LIBRARIES
如果_FOUND為真,把_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中。

編寫屬于自己的FindHello模塊:
1.FIND_PATH(HELLO_INCLUDE_DIR hello.h /usr/include/hello /usr/local/include/hello)
2.FIND_LIBRARY(HELLO_LIBRARY_DIR NAMES hello PATH /usr/lib /usr/local/lib)
  IF(HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
  SET(HELLO_FOUND TRUE)
  ENDIF(HELLO_INCLUDE_DIR)
3.FIND_PACKAGE([major.minor][QUIET][NO_MODULE]
[[REQUIRED|COMPONENTS][componets...]])
QUIET參數(shù):去掉輸出信息
REQUIRED參數(shù):共享庫是否是工程必須的,如果是必須的,那么找不到
如果在src中想調(diào)用hello模塊中的內(nèi)容
FIND_PACKAGE(HELLO)
為了可以讓工程找到FindHELLO.cmake
在主工程的CMakeList.txt中,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_PATH}/cmake)
通過設置FIND_PACKAGE(HELLO QUIET)可以去掉輸出信息

Cmake CMAKE_BUILD_TYPE specification

That’s because no build type has been specified to CMake. The build type is a feature most IDE have, it allows you to compile your program in “debug” mode, for easily single-stepping through it with a debugger, or in “release” mode, with speed optimization enabled.

To fix this you simply need to specify a build type in the CMakeLists.txt file, in this way:


if( NOT CMAKE_BUILD_TYPE )
  set( CMAKE_BUILD_TYPE Debug CACHE STRING
       "Choose the type of build, options are: None Debug Release RelWithDebInfo
MinSizeRel."
       FORCE )
endif()

when cmake is run without specifying the build type using -D CMAKE_BUILD_TYPE, it is the Debug mode that is selected as the default.


 

posted @ 2016-09-11 22:52 Daywei 閱讀(1286) | 評論 (0)編輯 收藏

SDL認識

     SDL是一個輕量級的,用C語言開發(fā)的多媒體庫。它包含了圖像繪制、文字繪制、事件處理、聲音播放等模塊。因為SDL的易用以及它的擴展庫的完整性,很多2D游戲都使用SDL開發(fā),其中就包括這幾年大熱的移動平臺上的游戲《憤怒的小鳥》。

然后說說從個人角度上看SDL的特點。

1.跨平臺。確確實實是跨了N個平臺,甚至包括NDS這種平臺。有了SDL,你甚至可以在windows、linux、Android上任意移植你的游戲。當然,前提是你目標平臺的編譯器認識你的代碼( ̄▽ ̄)”。有了SDL泥甚至可以只用c語言開發(fā)安卓游戲喲。

2.開源。

3.SDL2.0繪圖效率很高。事實上相較之SDL1.2我個人比較喜歡SDL2.0的原因也是在此。個人感覺(其實我沒看過源碼)SDL1.2應該是個跟當年的DirectDraw差不多的東西,像素填充什么的,有相當程度上是要磨CPU的。而SDL2.0從繪圖方式上就革新了,拋棄了之前的surface與clip的模式,把實際繪制的東西改為了Texture,而把之前的surface改為了創(chuàng)建Texture的一個臨時環(huán)節(jié)。而texure,顧名思義,其實就是DirectX、OpenGL這些底層的3D硬件加速API的貼圖。

當下DirectX、OpenGL標準下的顯卡的渲染管線無非就是:1.把頂點(可以理解成坐標)傳給顯卡 。2.把texture傳給顯卡。 3.告訴顯卡怎么處理這些數(shù)據(jù)(shader)。 4.顯卡把東西給你顯示出來。而基于DirectX、OpenGL(移動平臺是OpenGL ES)的SDL2.0,正是恰好地利用了當下顯卡的能力。

4.SDL可以用作3D圖像引擎和底層DirectX/OpenGL API的中間層。當然,其實如果把SDL這樣用的話,那就真是很薄的一層了:)

5.易用。這是相對而言的,比如在windows上,你用了SDL這個庫之后,基本就不用去理會Windows那些又臭又長用不著的參數(shù)又多的API了。我不是在討論信仰問題也不是要詆毀windows,我是在客觀陳述windows api那個要初始化一個窗口必須要堆100行代碼的設定實在是打擊初學者積極性的事實。

SDL_image、SDL_ttf、SDL_mixer、SDL_net 外部擴展庫,也是不錯的選擇。

性能沒有測試,僅從寫代碼角度上來說,個人感覺2.0將操作給弄得復雜了。

1.2---------------------------------------
只有SDL_Surface的概念,屏幕是surface,圖片,文字等都是surface,
只要將準備好的各種圖片,貼到屏幕里去(SDL_BlitSurface);再刷一下屏幕(SDL_Flip全局的、或SDL_UpdateRect局部的)就ok了。。。

SDL_Init(SDL_INIT_EVERYTHING);

SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
SDL_Surface* bmp = SDL_LoadBMP("back.bmp");
SDL_BlitSurface(bmp, 0, screen, 0);
SDL_Flip(screen);

while(SDL_WaitEvent(&e)) {
switch(e.type) {
case SDL_QUIT:
return;
}
}
SDL_Quit();
2.0---------------------------------------
整出了SDL_Window,SDL_Renderer,SDL_Texture新的3個東西。
并且我要畫一張圖,先要得到surface,然后轉(zhuǎn)換為texture,再臨時貼到renderer,最后才刷屏。

SDL_Init(SDL_INIT_EVERYTHING);

SDL_Window* window = SDL_CreateWindow("hello", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Surface* surface = SDL_LoadBMP("back.bmp");
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, 0, 0);
SDL_RenderPresent(renderer);

while(SDL_WaitEvent(&e)) {
switch(e.type) {
case SDL_QUIT:
return;
}
}
SDL_Quit();

其實,我真心不覺得提出SDL_Window,SDL_Renderer,SDL_Texture這些概念先進性在哪里?可能是與openGL的概念保持一致吧。
而且從維護的角度出發(fā),不管sdl2.0性能提升了多少,如果接口本身不需要改動,不是更加好么?

---------------------------------------------
最后我發(fā)現(xiàn),同樣是渲染的窗口
1.2用SDL_Flip(screen);之后被其他窗口擋住之后,回來畫面還是在的;
2.0用SDL_RenderPresent(renderer);之后被其他窗口擋住之后,回來畫面就不在了;

posted @ 2016-06-28 00:17 Daywei 閱讀(712) | 評論 (0)編輯 收藏

OpenCV 使用問題記錄

     摘要:     OpenCV從1.0到現(xiàn)在的3.0,變化還是相當大的。大趨勢是從C結(jié)構(gòu)層次到C++類層次的轉(zhuǎn)變。先從OpenCV底層的圖像數(shù)據(jù)結(jié)構(gòu)談起,1.0時 圖像數(shù)據(jù)結(jié)構(gòu)是IplImage,之后是cvmat,之后2.2中出現(xiàn)了CvvImage,之后就是cv::mat,2.3之后CvvImage就被廢棄了。 opencv中對圖像的處理是最基本的操作,一般的圖像類型為Ipl...  閱讀全文

posted @ 2015-12-06 12:20 Daywei 閱讀(1984) | 評論 (0)編輯 收藏

SQL使用記錄

     摘要: 問題:Update字段來自子查詢或者來自其他表字段 Update 語句 Update 語句用于修改表中的數(shù)據(jù)。 語法:UPDATE 表名稱 SET 列名稱 = 新值 WHERE 列名稱 = 某值SQL update select語句 最常用的update語法是: UPDATE <table_name> SET <column_name1> = <value&...  閱讀全文

posted @ 2015-03-17 15:43 Daywei 閱讀(777) | 評論 (0)編輯 收藏

Exceptional C++ 讀書筆記2

永遠不要用#include包含不必要的頭文件

如果只需要流的前置聲明,應該優(yōu)先使用#include<iosfwd>

只需要前置聲明時,絕不要用#include包含相應的頭文件。

如果使用聚合關系就已經(jīng)足夠,就不要使用繼承。

要避免使用內(nèi)聯(lián)或者復雜的調(diào)整方法,除非通過性能分析證明這確實是必要的。

正確使用名字空間。如果將一個類放入名字空間,那么同時要保證將這個類的所有輔助函數(shù)和運算符函數(shù)也放入相同的名字空間。否則,你將在代碼中發(fā)現(xiàn)奇怪的結(jié)果。
要理解這五種不同類型的內(nèi)存,了解他們?yōu)槭裁词遣煌?,以及他們各自的行為又是怎么樣:棧(自動變量)、自由存儲(new/delete)、堆(malloc/free)、全局(靜態(tài)變量、全局變量、文件作用域變量等)、常量數(shù)據(jù)(字符串常量等)。

優(yōu)先使用自由存儲(new/delete),避免使用堆(malloc/free)。

對于“堆”和“自由存儲”進行區(qū)分,這一點很重要,因為在C++標準中有意避開了這兩種類型的內(nèi)存是不是相關的這個問題。例如,當通過::operator delete()函數(shù)來釋放內(nèi)存時,在C++標準的18.4.1.1中,最后一項是這樣的:
“ 在C++標準中并沒有規(guī)定,在哪些情況下,在通過operator delete回收的存儲空間中,有一部分或者全部的控件可以再隨后調(diào)用operator new或者calloc,malloc以及realloc等函數(shù)時被重新分配,這些函數(shù)的聲明時在<cstdlib>中。”
而且,在C++標準中也沒有規(guī)定,new/delete是否需要通過malloc/free來實現(xiàn)。不過,在C++標準20.4.6節(jié)的第3段和第4段中規(guī)定了,malloc/free一定不能使用new/delete來實現(xiàn):“calloc、malloc和realloc函數(shù)不會通過調(diào)用::operator new()來分配存儲空間。函數(shù)free()不會通過調(diào)用::operator delete() 來釋放內(nèi)存。”

如果在類中定義了new和delete中的任意一個運算符函數(shù),那么一定要同時定義另外一個。

通常應該顯式地將函數(shù)operator new ()和operator delete()聲明為靜態(tài)函數(shù)。他們永遠都不能使非靜態(tài)成員函數(shù)。

永遠都不要通過多態(tài)的方式處理數(shù)組。

優(yōu)先選擇使用vector或者deque,而不是數(shù)組。

在編寫拷貝賦值運算符函數(shù)時,永遠都不要指望能夠通過對自我賦值進行檢測來保證函數(shù)的正確性;應該在拷貝賦值運算符函數(shù)中使用“創(chuàng)建臨時對象并進行交換”的慣用法,這種方法不僅是異常安全的,而且在處理自我賦值時也是安全的。

可以將自我賦值檢測作為一種優(yōu)化手段,以避免不必要的工作,這是正確地做法。

不僅要避免編寫類型轉(zhuǎn)換運算符函數(shù),而且還要避免編寫隱式的構(gòu)造函數(shù)。

盡量編寫異常安全的代碼。在編寫代碼時應該始終遵循:即使在出現(xiàn)異常時,資源仍然能夠被正確地釋放,并且數(shù)據(jù)也總是處于一致的狀態(tài)。

避免使用語言中那些不常用的特性,而應該使用最簡單并且有效的技術。

拷貝初始化過程絕不是賦值過程,因此在初始化中永遠都不會調(diào)用函數(shù)T::operator=()。是的,我知道在初始化語句中有一個“=”符合,但不要被它迷惑。它只是從C語言中沿用過來的一種語法,并不代表賦值運算。

如果可能的話,優(yōu)先使用“T t(u);”這種形式,而不是“T t=u;”的形式。通常,能能夠時候后者的地方,都可以使用前者,并且使用前者還有更多的好處——例如,可以帶多個參數(shù)。

在函數(shù)聲明中,如果參數(shù)是以傳值方式來傳遞的,則不要使用const。而如果在這個函數(shù)的定義中,參數(shù)是不能被修改的,那么應該使用const。

對于不是內(nèi)置類型的返回值來說,當使用返回值的方式而不是返回引用的方式時,應該優(yōu)先選擇返回const值。

const 和mutable都是你的朋友

優(yōu)先使用新形式的類型轉(zhuǎn)換。

不要通過類型轉(zhuǎn)換去掉常量屬性,而應該使用mutable。

避免使用向下的類型轉(zhuǎn)換。

優(yōu)先通過引用方式來傳遞對象參數(shù),而不是傳值方式,并且在所有可能的地方都使用const。

避免使用內(nèi)聯(lián),除非從性能的分析上來看確實有必要這么做。

避免使用全局變量或者靜態(tài)變量。如果必須使用,那么一定要特別注意這些變量的初始化順序。

在構(gòu)造函數(shù)的初始化列表中,應該把 基類按照他們在類定義中出現(xiàn)的先后順序進行排列。

在編寫代碼時,永遠都不應該依賴函數(shù)參數(shù)的求值順序

posted @ 2014-08-22 15:00 Daywei 閱讀(1557) | 評論 (0)編輯 收藏

Exceptional C++ 讀書筆記1

絕對不要對無效的迭代器執(zhí)行解引用(dereference)操作

用于不要將異常安全性放在事后考慮。異常安全性會影響到類的設計。它永遠都不會“只是一個實現(xiàn)細節(jié)”。

在傳遞對象參數(shù)時,選擇const&方式而不是傳值方式。

對于程序運行中不會改變的值,應該預先計算并保存起來備用,而不是重復地創(chuàng)建對象,這是沒有必要的。

通常,為了保持一致性,應該使用前置遞增來實現(xiàn)后置遞增,否則,當其他用戶在使用你的類時,可能會得到奇怪結(jié)果。

優(yōu)先選擇使用前置遞增。只有在需要初始值時,才使用后置遞增。

在進行隱式類型轉(zhuǎn)換時,要注意在轉(zhuǎn)換過程中創(chuàng)建的 臨時對象。要避免這個問題,一個好辦法就是盡可能地通過顯式的方式來構(gòu)造對象,并避免編寫類型轉(zhuǎn)換運算符。

記住對象的生存期。永遠,永遠,永遠都不要返回指向局部對象的指針或引用;它們沒有任何用處,因為主調(diào)代碼無法跟蹤它們的有效性,但卻可能會試圖這么做。

盡可能地重用代碼——尤其是標準庫中的代碼——而不是自己去編寫代碼,這樣更快、更容易,也更安全。

如果在函數(shù)中不打算處理所拋出的異常,那么應該將異常轉(zhuǎn)發(fā)給能夠進行處理的上層調(diào)用者。

在編寫代碼時應該始終遵循:即使在出現(xiàn)異常時,資源仍然能夠被正確地釋放,并且數(shù)據(jù)也總是處于一致的狀態(tài)。

遵循標準的異常安全規(guī)則:永遠不要在析構(gòu)函數(shù)、重載運算符函數(shù)operator delete()或者operator delete[]()中拋出異常; 在編寫每個析構(gòu)函數(shù)和內(nèi)存釋放函數(shù)時,要假設存在著“throw()”這樣的異常規(guī)范。

遵循標準的異常安全性規(guī)則:在每個函數(shù)中,要將所有可能會拋出異常的代碼單獨放在一起,并且對這些代碼進行安全處理。然后,當你確認這些代碼執(zhí)行的工作都已經(jīng)成功地完成時,才可以使用不會拋出異常的操作來修改程序的狀態(tài)。

永遠都不要到最后才實現(xiàn)異常安全性。異常安全性會對類的設計產(chǎn)生影響。它永遠都不會“只是一個實現(xiàn)細節(jié)”。

優(yōu)先考慮實現(xiàn)內(nèi)聚。要努力使每段代碼——每個模塊、每個類、每個函數(shù)——都只有單一的,并且是明確定義的功能。

“異常不安全”總是與“拙劣的設計”結(jié)伴的。如果程序的設計邏輯清晰,那么即使有一段代碼不是異常安全的,一般來說也不會有太大問題,并且可以很簡單地進行修正。但如果有一段代碼由于設計問題而不能被編寫成異常安全的,我們通常都會認為這個設計時拙劣的。下面是兩個拙劣設計的示例。
示例1:如果在一個函數(shù)中需要實現(xiàn)兩個不同的功能,那么這個函數(shù)很難被編寫成異常安全的。
示例2:如果在拷貝賦值運算符函數(shù)中必須對自我賦值進行檢測,那么這個函數(shù)也可能不是完全異常安全的

遵循標準的異常安全性規(guī)則:以“獲得資源也就意味著初始化”這種模式來分離資源的所有權和資源的管理權。

在進行設計中,要始終牢記重用性。

優(yōu)先采用“ a op=b;”這種寫法,而不是"a = a op b;"(這里的op表示某個運算符)。這種寫法更為清晰,效率也高。

如果定義了某個運算符(例如,operator+),那么通常還應該同時定義與這個運算符相對應的賦值運算符(例如,operator+=)。并且用后者來實現(xiàn)前者。而且,還應該維護op和op=之間的自然關系。

在C++標準中規(guī)定:運算符=,(),[]和->必須被定義為成員函數(shù),而在類中定義的new,new [],delete和delete[]等運算符函數(shù)必須是靜態(tài)成員函數(shù)。對于其他的運算符函數(shù):
     如果運算符函數(shù)是用于流I/O的opeator>>或者operator<<,或者如果運算符函數(shù)需要對其左操作數(shù)進行類型轉(zhuǎn)換,或者運算符函數(shù)可以通過類的公有接口來實現(xiàn),那么將這個函數(shù)定義為非成員函數(shù)(在前兩種情況中,如果需要的話也可以被定義為友元函數(shù));如果運算符函數(shù)需要實現(xiàn)虛函數(shù)的行為,那么增加一個虛函數(shù)來提供虛函數(shù)的行為,并用這個虛成員函數(shù)來實現(xiàn)運算符函數(shù)否則將預算富函數(shù)定義為成員函數(shù)。

在函數(shù)opeator>>和operator<<中應該始終返回對流對象的引用。

將基類的析構(gòu)函數(shù)定義為虛函數(shù)(除非你能保證,永遠都不會有人通過指向基類的指針來刪除派生類的對象)。

如果在派生類中定義的函數(shù)與基類中的函數(shù)有相同的名字,并且你不想隱藏基類中函數(shù),那么應通過using聲明語句將基類的這個函數(shù)引入到派生類的作用域中。

永遠不要改變被覆蓋的基類函數(shù)中的默認參數(shù)值。

除了對真正的Liskov IS-A和WORKS-LIKE-A關系進行建模之外,永遠都不要使用共有繼承。所有被覆蓋的成員函數(shù)不能超過實際需求的范圍,同時也不能小于這個范圍。

使用公有繼承的目的是重用代碼(編寫以多態(tài)的方式使用基類對象的代碼),而重用(基類中的)代碼并不一定要使用公有繼承。

對“is implemented in terms of”這種關系建模時,應該優(yōu)先選擇成員關系/包含的方式,而不是私有繼承的方式。只有非用繼承不可時,才應該使用私有繼承——也就是說,當需要訪問保護成員或者需要覆蓋虛函數(shù)時,才使用私有繼承。永遠都不要只是為了代碼重用而使用共有繼承。

對于廣泛使用的類,應該優(yōu)先使用編譯器防火墻這種慣用法(也叫做Pimpl慣用法)來隱藏實現(xiàn)細節(jié),通過一個不透明的指針(指向一個進行了前置聲明但又沒有定義的類)來保存私有成員(包括狀態(tài)變量和成員函數(shù)),聲明這個指針時可采用“struct XxxxImpl* pImpl;XxxxImpl* pimpl_;”這樣的形式。例如:“class map{ private :struct MapImpl;MapImpl* pimpl_;}”

包含,也可以叫做“聚合”,“分層”,“HAS-A”或者“委托”。優(yōu)先選擇包含而不是繼承,對于IS-IMPLEMENTED-IN-TERMS-OF這種關系建模時,應該優(yōu)先考慮使用包含,而不是繼承。

posted @ 2014-08-22 11:50 Daywei 閱讀(1617) | 評論 (0)編輯 收藏

從缺陷中學習C/C++


有符號int與無符號int比較的后果
int i = -1;
unsigned 
int ud=1;
if(i < ud)
{
    printf(
"true");
}

else
{
    printf(
"false");
}
一看結(jié)果應該是打印出true,但事實卻是false。
signed int 型變量被轉(zhuǎn)換成unsigned int型變量。-1轉(zhuǎn)換成unsigned int的結(jié)果是一個非常巨大的正整數(shù)(32位系統(tǒng)上是2的32次方-1),需要進行強轉(zhuǎn)為int型。

位域變量
struct data
{
int flag:1;
int other:31;
}
;
printf(
"data size %d\n",sizeof(data));
data test1;
test.flag
= 1;
if(test.flag ==1)
{
printf(
"true");
}

else
{
printf(
"false");
}
int的位域變量,而用一個bit表示int時,這一位是用來表示有符號位的,帶符號的一個bit的位域變量的取值范圍是0或-1.無符號的一個bit的位域變量的取值范圍是0或1,故1賦給flag時會出現(xiàn)溢出,flag變?yōu)?1.
Reference:http://wenku.baidu.com/view/670eff4bf7ec4afe04a1dfd7.html

posted @ 2014-07-24 15:29 Daywei 閱讀(1405) | 評論 (0)編輯 收藏

Effective STL(5)——算法

1.確保目標空間足夠大

2.了解各種與排序有關的選擇
  如果需要對vector、string、deque或者數(shù)組中的元素執(zhí)行一次完全排序,那么可以使用sort或者stable_sort。
  如果有一個vector、string、deque或者數(shù)組,并且只需要對等價性最前面的n個元素進行排序,那么可以使用partial_sort。
  如果有一個vector、string、deque或者數(shù)組,并且需要找到第n個位置上的元素,或者,需要找到等價性最前面的n個元素但又不必對這n個元素進行排序,那么,nth_element正是你所需要的函數(shù)。
  如果需要將一個標準序列容器中的元素按照是否滿足某個特定的條件區(qū)分開來,那么,partition和stable_partition可能正是你所需要的。
  如果你的數(shù)據(jù)在一個list中,那么你仍然可以直接調(diào)用partition和stable_partition算法;可以用list::sort來替代sort和stable_sort算法。但是,如果你需要獲得partial_sort或nth_element算法的效果,那么,正如前面我所提到的那樣,你可以有一些簡潔的途徑來完成這項任務。

3。如果確實需要刪除元素,則需要在remove這一類算法之后調(diào)用erase。

   remove不是真正意義上的刪除,因為它做不到。

4.對包含指針的容器使用remove這一類算法時要特別小心。會導致資源泄露。

5.了解哪些算法要求使用排序的區(qū)間作為參數(shù)。

6.通過mismatch或lexicographical_compare實現(xiàn)簡單地忽略大小寫的字符串比較

7.理解copy_if算法的正確實現(xiàn)

8.使用accumlate或者for_each進行區(qū)間統(tǒng)計。

posted @ 2014-06-25 17:06 Daywei 閱讀(1469) | 評論 (0)編輯 收藏

Effective STL(4)——迭代器

1.iterator 優(yōu)先于const_iterator、reverse_iterator及const_reverse_iterator

2.使用distance和advace將容器的const_iterator轉(zhuǎn)換成iterator

3.正確理解由reverse_iterator的base()成員函數(shù)所產(chǎn)生的iterator的用法。

4.對于逐個字符的輸入請考慮使用istreambuf_iterator

posted @ 2014-06-13 15:00 Daywei 閱讀(1296) | 評論 (0)編輯 收藏

Effective STL(3)——關聯(lián)容器

1.理解相等(equality)和等價(equivalence)的區(qū)別

相等的概念是基于operator==的。等價關系是以“在已排序的區(qū)間中對象值得相對順序”為基礎的。如果從每個標準關聯(lián)容器的排列順序來考慮等價關系,那么著將是有意義的。標準關聯(lián)容器室基于等價而不是相等的。標準關聯(lián)容器總是保持排列順序的,所以每個容器必須有一個比較函數(shù)(默認less)來決定保持怎樣的順序。等價是按照比較函數(shù)子。因此,標準關聯(lián)容器的使用者要為所使用的每個容器指定一個比較函數(shù)(用來決定如何排序)。如果該關聯(lián)容器使用相等來決定兩個對象是否有相同的值,那么每個關聯(lián)容器除了用于排序的比較函數(shù)外,還需要另一個比較函數(shù)來決定兩個值是否相等(默認情況下,該比較函數(shù)應該是equal_to,但有趣的是equal_to從來沒有被用做STL的默認比較函數(shù)。當STL中需要相等判斷時,一般的慣例是直接調(diào)用operator==。比如,非成員函數(shù)find算法就是這么做的)

2.為包含指針的關聯(lián)容器指定比較類型

why?第一條已經(jīng)說明關聯(lián)容器是要排序。每當你要創(chuàng)建包含指針的關聯(lián)容器時,一定要記住,容器將會按照指針的值進行排序。一般是不是你希望的,所以你幾乎要創(chuàng)建自己的函數(shù)子類作為該容器的比較類型。

3.總是讓比較函數(shù)在等值情況下返回false

比較函數(shù)的返回值表明的是按照該函數(shù)定義的排列順序,一個值是否在另一個之前。相等的值從來不會有前后順序關系,所以,對于相等的值,比較函數(shù)應該始終返回false。

4.切勿直接修改set或multiset中的鍵。

5。考慮用排序的vector替代關聯(lián)容器

在排序的vector中存儲數(shù)據(jù)可能比在標準關聯(lián)容器中存儲同樣的數(shù)據(jù)要耗費更少的內(nèi)存,而考慮到頁面錯誤的因素,通過二分搜索法來查找一個排序的vector可能比查找一個標準關聯(lián)容器要更快一些。

6.當效率至關重要時,請在map::operator[]與map::insert之間謹慎做出選擇

map::operator[]的設計目的是為了提供“添加和更新”的功能。添加一個新元素最好選后者insert。

7.熟悉非標準的散列容器。

posted @ 2014-05-16 16:30 Daywei 閱讀(1358) | 評論 (0)編輯 收藏

僅列出標題
共4頁: 1 2 3 4 
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

導航

統(tǒng)計

常用鏈接

留言簿

隨筆分類

隨筆檔案

文章檔案

牛人博客

搜索

積分與排名

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩无遮挡| 亚洲少妇最新在线视频| 欧美影视一区| 国产在线日韩| 欧美va天堂va视频va在线| 欧美丰满高潮xxxx喷水动漫| 亚洲美女视频在线观看| 99热免费精品| 国产日韩欧美一区二区三区四区| 久久亚洲二区| 免费欧美在线| 亚洲女人天堂av| 欧美一区三区二区在线观看| 伊人久久大香线蕉综合热线| 91久久精品国产91性色| 国产精品xvideos88| 久久成人精品视频| 欧美韩日精品| 欧美一区二区在线| 欧美v日韩v国产v| 亚洲一区二区三区免费在线观看 | 久久久久久久国产| 欧美大片免费久久精品三p | 亚洲欧美日韩系列| 亚洲黄色免费电影| 亚洲影音先锋| 日韩视频精品在线| 欧美一级片久久久久久久| 亚洲国产精品美女| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产午夜精品全部视频播放 | 亚洲在线观看免费视频| 久久精品视频99| 中文亚洲欧美| 欧美大片91| 蜜桃av噜噜一区二区三区| 国产精品第一页第二页第三页| 久久中文字幕一区| 国产精品户外野外| 亚洲人在线视频| 亚洲高清视频一区| 欧美一区高清| 香蕉久久a毛片| 欧美国产先锋| 久久国产欧美精品| 欧美一区二区三区男人的天堂| 久久视频在线看| 久久福利资源站| 欧美午夜视频在线| 亚洲欧洲精品成人久久奇米网| 国外成人在线视频| 欧美一级成年大片在线观看| 亚洲欧美另类综合偷拍| 欧美日韩八区| 最新中文字幕一区二区三区| 在线观看不卡| 久久色在线播放| 老司机精品视频网站| 国产欧美1区2区3区| 亚洲视频1区2区| 亚洲尤物在线视频观看| 欧美色道久久88综合亚洲精品| 亚洲国产欧美日韩精品| 亚洲精品123区| 蜜臀av一级做a爰片久久| 欧美成人精品三级在线观看| 在线观看国产精品淫| 久久久久女教师免费一区| 美日韩在线观看| 亚洲精品久久在线| 欧美国产在线电影| av成人毛片| 久久www成人_看片免费不卡| 国产视频在线观看一区二区三区| 亚洲女女女同性video| 久久国产精品久久久久久电车| 国产精品一区毛片| 欧美在线你懂的| 欧美成人一区二区三区在线观看| 亚洲国产精品一区二区久| 另类av一区二区| 亚洲日本免费| 亚洲摸下面视频| 国产综合亚洲精品一区二| 久久免费视频在线观看| 亚洲欧洲精品成人久久奇米网| 在线中文字幕日韩| 国产精品一页| 麻豆精品精华液| 日韩午夜一区| 久久久久久久综合日本| 影音先锋中文字幕一区| 欧美激情一二区| 亚洲欧美精品伊人久久| 免费在线欧美黄色| 亚洲愉拍自拍另类高清精品| 韩日欧美一区二区| 欧美日韩国产色视频| 亚洲欧美一区二区三区在线| 欧美成人a视频| 亚洲一级一区| 亚洲黄页视频免费观看| 国产精品久久二区| 免费成人毛片| 亚洲男女自偷自拍图片另类| 欧美成人精品一区二区三区| 亚洲天堂av电影| 在线欧美日韩| 国产精品国产| 欧美高清视频在线| 久久精品国产欧美激情| 99热这里只有成人精品国产| 久久婷婷国产综合国色天香| 亚洲天堂av综合网| 亚洲欧洲视频| 欧美成人高清视频| 久久久久久久综合狠狠综合| 一区二区不卡在线视频 午夜欧美不卡在| 国产模特精品视频久久久久 | 久久综合狠狠综合久久综青草| 一区二区三区欧美激情| 美女黄色成人网| 亚洲欧美日韩高清| 亚洲一区二区三区激情| 亚洲美女91| 亚洲国产日韩综合一区| 黄色日韩在线| 国产偷自视频区视频一区二区| 国产精品h在线观看| 欧美人与禽性xxxxx杂性| 久久久天天操| 久久精品亚洲国产奇米99| 亚洲私拍自拍| 一区二区三区|亚洲午夜| 亚洲国产精品va| 欧美激情第10页| 麻豆精品精华液| 久久一二三国产| 久久综合色影院| 久久蜜桃香蕉精品一区二区三区| 羞羞视频在线观看欧美| 亚洲欧美中日韩| 欧美在线日韩在线| 久久精品天堂| 久久亚洲色图| 欧美岛国激情| 亚洲国产成人av好男人在线观看| 老司机精品视频网站| 欧美国产第一页| 亚洲国产精品免费| 亚洲精品一区二区三区在线观看| 91久久综合| 一区二区三区高清在线观看| 亚洲美女福利视频网站| 亚洲特色特黄| 亚洲欧美中日韩| 久久久久综合网| 欧美高清视频一二三区| 欧美日韩亚洲高清一区二区| 国产精品美女久久久| 国产日韩高清一区二区三区在线| 国产亚洲精品久久久久婷婷瑜伽| 国产综合自拍| 亚洲精品影视| 午夜视频久久久| 免费在线成人| 亚洲精品乱码久久久久久日本蜜臀 | 性欧美xxxx视频在线观看| 久久成人一区二区| 欧美黄色一级视频| 国产精品日本欧美一区二区三区| 国产日韩欧美综合一区| 亚洲激情视频在线| 亚洲免费一在线| 欧美激情中文不卡| 中日韩美女免费视频网址在线观看| 亚洲欧美国产毛片在线| 乱中年女人伦av一区二区| 欧美日韩免费观看一区=区三区| 国产日韩亚洲| 一本色道久久加勒比精品| 欧美在线精品免播放器视频| 欧美成人精品在线观看| 国产精品99久久久久久www| 久久精品中文| 国产精品久久久久91| 亚洲国产精品久久久久| 欧美一区二区精品| 亚洲国产精品成人综合色在线婷婷| 亚洲视频视频在线| 国产精品中文字幕在线观看| 亚洲电影观看| 午夜在线播放视频欧美| 亚洲电影在线看| 欧美在线不卡| 国产精品视频你懂的| 亚洲精品视频在线播放| 久久久久久综合| 亚洲欧美在线一区| 国产精品美女主播|