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

2016年9月11日

CMake使用

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

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


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

二、添加靜態(tài)庫:
ADD_LIBRARY(hello STATIC ${STATIC_LIBRARY})
因?yàn)槟J(rèn)規(guī)則是不能有相同名字的共享庫與靜態(tài)庫,所以當(dāng)生成靜態(tài)庫的時(shí)候(so后綴),共享庫會被刪除,因?yàn)橹荒茉试S一個(gè)名字存在,相同名字的會被替代(hello),所以需要通過SET_TARGET_PROPERTIES()來解決這個(gè)問題,例子:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
cmake在構(gòu)建一個(gè)target的時(shí)候,會刪除之前生成的target,一樣是通過設(shè)置SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)來達(dá)到目的
三、動態(tài)庫的版本號:
同樣是通過SET_TARGET_PROPERTIES()來設(shè)置
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:設(shè)置權(quán)限;RATTERN:設(shè)置正則表達(dá)式


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

cmake學(xué)習(xí)(二)常用變量和常用環(huán)境變量
一、變量的引用方式是使用“${}”,在IF中,不需要使用這種方式,直接使用變量名即可
二、自定義變量使用SET(OBJ_NAME xxxx),使用時(shí)${OBJ_NAME}
三、cmake的常用變量:
CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR:
這三個(gè)變量內(nèi)容一致,如果是內(nèi)部編譯,就指的是工程的頂級目錄,如果是外部編譯,指的就是工程編譯發(fā)生的目錄。
CMAKE_SOURCE_DIR,PROJECT_SOURCE_DIR,_SOURCE_DIR:
這三個(gè)變量內(nèi)容一致,都指的是工程的頂級目錄。
CMAKE_CURRENT_BINARY_DIR:外部編譯時(shí),指的是target目錄,內(nèi)部編譯時(shí),指的是頂級目錄
CMAKE_CURRENT_SOURCE_DIR:CMakeList.txt所在的目錄
CMAKE_CURRENT_LIST_DIR:CMakeList.txt的完整路徑
CMAKE_CURRENT_LIST_LINE:當(dāng)前所在的行
CMAKE_MODULE_PATH:如果工程復(fù)雜,可能需要編寫一些cmake模塊,這里通過SET指定這個(gè)變量
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學(xué)習(xí)(三)常用指令

一、基本指令:
INCLUDE_DIRECTORIES(${includedir}) #-I。
LINK_DIRECTORIES(${libdir}) #-L
TARGET_LINK_LIBRARIES(helloworld ${linkflags}) #-l
ADD_DEFINITIONS(${cflags}) #-D
 
1、ADD_DEFINATIONS:向C/CPP添加宏定義,相當(dāng)于gcc中的-D,參數(shù)之間用空格分割
2、ADD_DEPENDICIES(target_name, depend_name):定義target對其他target的依賴關(guān)系
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學(xué)習(xí)(四)模塊的使用和自定義模塊

FIND_PACKAGE
每一個(gè)模塊都會產(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)
通過設(shè)置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 閱讀(1288) | 評論 (0)編輯 收藏

2016年6月28日

SDL認(rèn)識

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

然后說說從個(gè)人角度上看SDL的特點(diǎn)。

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

2.開源。

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

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

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

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

SDL_image、SDL_ttf、SDL_mixer、SDL_net 外部擴(kuò)展庫,也是不錯(cuò)的選擇。

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

1.2---------------------------------------
只有SDL_Surface的概念,屏幕是surface,圖片,文字等都是surface,
只要將準(zhǔn)備好的各種圖片,貼到屏幕里去(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個(gè)東西。
并且我要畫一張圖,先要得到surface,然后轉(zhuǎn)換為texture,再臨時(shí)貼到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();

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

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

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

2015年12月6日

OpenCV 使用問題記錄

     摘要:     OpenCV從1.0到現(xiàn)在的3.0,變化還是相當(dāng)大的。大趨勢是從C結(jié)構(gòu)層次到C++類層次的轉(zhuǎn)變。先從OpenCV底層的圖像數(shù)據(jù)結(jié)構(gòu)談起,1.0時(shí) 圖像數(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 閱讀(1993) | 評論 (0)編輯 收藏

2015年3月17日

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 閱讀(780) | 評論 (0)編輯 收藏

2014年8月22日

Exceptional C++ 讀書筆記2

永遠(yuǎn)不要用#include包含不必要的頭文件

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

只需要前置聲明時(shí),絕不要用#include包含相應(yīng)的頭文件。

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

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

正確使用名字空間。如果將一個(gè)類放入名字空間,那么同時(shí)要保證將這個(gè)類的所有輔助函數(shù)和運(yùn)算符函數(shù)也放入相同的名字空間。否則,你將在代碼中發(fā)現(xiàn)奇怪的結(jié)果。
要理解這五種不同類型的內(nèi)存,了解他們?yōu)槭裁词遣煌模约八麄兏髯缘男袨橛质窃趺礃樱簵#ㄗ詣幼兞浚⒆杂纱鎯Γ╪ew/delete)、堆(malloc/free)、全局(靜態(tài)變量、全局變量、文件作用域變量等)、常量數(shù)據(jù)(字符串常量等)。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

const 和mutable都是你的朋友

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

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

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

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

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

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

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

在編寫代碼時(shí),永遠(yuǎn)都不應(yīng)該依賴函數(shù)參數(shù)的求值順序

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

Exceptional C++ 讀書筆記1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

在進(jìn)行設(shè)計(jì)中,要始終牢記重用性。

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

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

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

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

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

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

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

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

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

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

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

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

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

2014年7月24日

從缺陷中學(xué)習(xí)C/C++


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

else
{
    printf(
"false");
}
一看結(jié)果應(yīng)該是打印出true,但事實(shí)卻是false。
signed int 型變量被轉(zhuǎn)換成unsigned int型變量。-1轉(zhuǎn)換成unsigned int的結(jié)果是一個(gè)非常巨大的正整數(shù)(32位系統(tǒng)上是2的32次方-1),需要進(jìn)行強(qiáng)轉(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的位域變量,而用一個(gè)bit表示int時(shí),這一位是用來表示有符號位的,帶符號的一個(gè)bit的位域變量的取值范圍是0或-1.無符號的一個(gè)bit的位域變量的取值范圍是0或1,故1賦給flag時(shí)會出現(xiàn)溢出,flag變?yōu)?1.
Reference:http://wenku.baidu.com/view/670eff4bf7ec4afe04a1dfd7.html

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

2014年6月25日

Effective STL(5)——算法

1.確保目標(biāo)空間足夠大

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

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

   remove不是真正意義上的刪除,因?yàn)樗霾坏健?br />
4.對包含指針的容器使用remove這一類算法時(shí)要特別小心。會導(dǎo)致資源泄露。

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

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

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

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

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

2014年6月13日

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.對于逐個(gè)字符的輸入請考慮使用istreambuf_iterator

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

2014年5月16日

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

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

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

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

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

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

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

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

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

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

6.當(dāng)效率至關(guān)重要時(shí),請?jiān)趍ap::operator[]與map::insert之間謹(jǐn)慎做出選擇

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

7.熟悉非標(biāo)準(zhǔn)的散列容器。

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

僅列出標(biāo)題  下一頁
<2014年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿

隨筆分類

隨筆檔案

文章檔案

牛人博客

搜索

積分與排名

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产日韩精品入口| 99成人在线| 久久久久国产精品一区三寸| 一本久久精品一区二区| 欧美激情免费观看| 欧美成人综合在线| 欧美激情国产日韩| 亚洲国产精品一区制服丝袜 | 99在线热播精品免费99热| 亚洲高清在线播放| 亚洲福利视频三区| 亚洲精品国久久99热| 日韩视频久久| 亚洲精选在线观看| 亚洲视频免费在线观看| 亚洲特黄一级片| 欧美一区二区视频在线| 久久精品女人天堂| 欧美激情aaaa| 一区二区高清在线| 午夜在线视频观看日韩17c| 久久久国产亚洲精品| 免费成人av在线| 欧美日韩国产首页在线观看| 国产精品嫩草99a| 伊人久久大香线蕉综合热线| 亚洲另类自拍| 欧美中文字幕在线播放| 欧美肥婆在线| 亚洲性感美女99在线| 久久精品国产精品亚洲综合| 久热精品在线视频| 国产精品国产三级欧美二区| 国产一区日韩欧美| 亚洲九九九在线观看| 久久久天天操| 亚洲男女自偷自拍| 欧美.www| 一本色道**综合亚洲精品蜜桃冫| 新67194成人永久网站| 欧美ed2k| 国产午夜亚洲精品羞羞网站| 亚洲精品日韩综合观看成人91| 亚洲女ⅴideoshd黑人| 欧美99在线视频观看| 亚洲网站视频| 欧美国产日韩精品免费观看| 国产日韩欧美综合| 亚洲一区在线视频| 你懂的网址国产 欧美| 亚洲主播在线观看| 欧美日韩性生活视频| 国内在线观看一区二区三区| 亚洲最新色图| 亚洲国产精品精华液网站| 久久动漫亚洲| 国产精品视频免费一区| 日韩视频在线一区| 久久综合伊人77777尤物| 一区二区三区日韩精品| 欧美日韩不卡| av成人免费| 亚洲精品自在在线观看| 欧美电影免费观看网站| 在线播放国产一区中文字幕剧情欧美| 欧美一级久久久| 亚洲在线不卡| 国产精品毛片a∨一区二区三区| 亚洲国产美国国产综合一区二区| 久久中文字幕一区| 久久av一区| 在线成人性视频| 欧美国产亚洲另类动漫| 狼人社综合社区| 亚洲欧洲精品天堂一级| 亚洲国产成人久久| 狼人社综合社区| 亚洲激情另类| 亚洲欧洲精品一区| 欧美日韩精品免费观看| 亚洲视频欧美在线| 亚洲网站在线看| 国产热re99久久6国产精品| 久久天天躁狠狠躁夜夜av| 久久久久一区二区三区| 亚洲精品乱码| 亚洲午夜小视频| 国产精品理论片| 久久亚洲欧美| 欧美激情一区二区| 亚洲网站在线播放| 亚洲欧美日本另类| 在线日韩av片| 亚洲国产小视频| 欧美丝袜第一区| 欧美在线观看视频| 国产欧美精品va在线观看| 小黄鸭精品密入口导航| 这里是久久伊人| 国产一区二区av| 亚洲第一福利视频| 欧美精品偷拍| 一区二区日韩免费看| 亚洲欧美日韩国产中文| 亚洲高清成人| 99热免费精品在线观看| 国内精品久久久| 亚洲国产美国国产综合一区二区| 欧美a级在线| 欧美一区二区三区播放老司机| 久久躁日日躁aaaaxxxx| 一本久道久久久| 亚洲欧美日韩中文在线制服| 91久久在线| 午夜日韩福利| 一本色道久久加勒比88综合| 久久av红桃一区二区小说| 亚洲夜晚福利在线观看| 久久夜色精品国产欧美乱| 亚洲欧美日韩精品久久久| 久久久综合视频| 亚洲自拍偷拍色片视频| 免费在线视频一区| 久久www成人_看片免费不卡| 免费人成网站在线观看欧美高清| 欧美亚洲综合久久| 欧美日韩国产成人在线免费| 欧美高清视频一二三区| 国产精品自拍视频| 99xxxx成人网| 一本色道久久加勒比88综合| 奶水喷射视频一区| 久久精品卡一| 国产精品永久| 夜夜精品视频一区二区| 亚洲七七久久综合桃花剧情介绍| 亚欧成人精品| 亚洲欧美国产高清| 欧美久久综合| 久久国产精品第一页| 久久不射2019中文字幕| 亚洲免费伊人电影在线观看av| 久久久成人网| 久久亚洲欧美| 影音先锋中文字幕一区| 欧美亚洲网站| 欧美一区二区三区在线免费观看 | 国产精品高清网站| 亚洲欧洲一区二区天堂久久| 亚洲人成在线影院| 欧美成人午夜激情| 亚洲国产日韩欧美| 在线看日韩欧美| 国产一区日韩二区欧美三区| 99这里只有精品| 亚洲一区二区三区午夜| 欧美日韩一区二区在线观看 | 先锋资源久久| 国产精品永久| 久久久九九九九| 欧美成人免费播放| 日韩视频―中文字幕| 欧美视频四区| 性色av一区二区怡红| 久久午夜电影网| 亚洲激情影院| 欧美日韩一区二区三区| 亚洲欧美网站| 麻豆国产va免费精品高清在线| 亚洲成色www8888| 欧美日韩国产一级| 欧美一区二区| 亚洲日本在线视频观看| 欧美呦呦网站| 久久在线免费| 99精品国产高清一区二区| 欧美一区免费视频| 亚洲黄色性网站| 国产精品美女一区二区在线观看| 国产精品99久久久久久宅男| 久久久一本精品99久久精品66| 亚洲人成亚洲人成在线观看| 国产精品亚洲综合天堂夜夜| 美国成人直播| 亚洲网站在线| 亚洲黄色天堂| 久久精品一区四区| 亚洲视频一区二区在线观看| 一区免费观看视频| 国产精品乱人伦一区二区| 欧美高清不卡在线| 午夜一区不卡| 99精品欧美一区| 欧美黄色片免费观看| 久久www成人_看片免费不卡 | 韩国成人理伦片免费播放| 欧美久久99| 久久一区二区视频| 香蕉国产精品偷在线观看不卡| 亚洲免费av电影|