C++编程原则1 tcy
生活随笔
收集整理的這篇文章主要介紹了
C++编程原则1 tcy
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.1.基本原則1)保持簡單和直接原則KISS( keep it simple ,stupid)2)不要原則YAGNI(You aren' gonna need it.)確定真的必要時在寫代碼;以后也許我們會用到....錯,你不會用到他3)避免復制原則DRY(Don't repeat yourself)4)信息隱藏原則 見實例15)高內聚松耦合 見實例2減少模塊之間的耦合,采用散譚槍反模式;邏輯思想高度碎片化,并且分散在許多模塊中,低內聚,嚴重相互依賴應將相同的代碼提取出來放在一個高內聚的模塊中一些其他原則單一職責SRP,會促進高內聚,高內聚往往時松耦合6)小心優化一般來說更改對性能的優化是微不足道的不局限于所謂的技巧,只要沒有明確的性能要求就避免優化7)最少驚訝原則PLA8)童子軍原則-發現不良及時修改重命名,將大函數變小來清理費解if-else;刪除重復代碼
?2.C++代碼整潔基本規范
2.1.良好的命名1)名稱應該自注釋;如上下文清晰用較短名稱如類成員2)選擇適當抽象層次的名稱;使用域中的名稱-專業術語3)避免冗余晦澀難懂名稱,避免同名用于不同目的4)不用匈牙利命名法,不加入類型信息 2.2.注釋不要為易懂代碼寫注釋;不要通過注釋禁用代碼不要寫塊注釋,不要用注釋代替版本控制;特殊算法需要添加注釋 2.3.數據:1)以適當方式訪問存儲實際內存中數據,數據分配應內存連續確保所有的數據結構都是cache行大小對齊2)不要將大量數據轉換為全局變量;推遲定義本地變量僅在需要時再定義盡量避免數據轉換期間可能發生數據拷貝,多次大小字節轉換3)避免在計算時進行動態內存分配對于單線程在堆上分配內存也比在棧上分配內存開銷大對于多線程需要等待分配器鎖和釋放內存4)避免不需要的數據初始化如果你需要初始化一大段的內存,考慮使用memset5)在STL容器中存儲指針-動態分配對象class Base {};class A : public Base{};std::vector <Base *> v;v.push_back(new A);v.push_back(new Base); delete v[0];delete v[1];std::vector <unique_ptr<Base>> v;v.push_back(make_unique<A>());v.push_back(make_unique<Base>()); 2.4.語法:1)盡量少用跳轉和分支;2)將循環內函數調用移動到循環外(for(i=0;i<100;i++) DoSomething();//改為DoSomething() { for(i=0;i<100;i++) { … }})3)優先使用迭代而不是遞歸;使用指令層的并行機制4)如果可以用>>,<<來代替整數乘除法5)小心使用模板調試STL庫非常低效6)盡量使用begin,end通用函數,允許更靈活和通用風格void view(const int& value){cout<<value<<endl;}for_each(begin(arr),end(arr),view);//C風格的數字迭代器以封裝好類似template<typename T,std::size_t size>T* begin(T(&element)([size]){return &element[0]}template<typename T,std::size_t size>T* end(T (&element)[size]){return &element[0]+size;}for(autoit=begin(arr);it!=end(arr);++it)cout<<*it<<endl; 2.5.函數 2.6.類:1)類實例應采用初始化而非賦值Color c(black); 比Color c; c = black;更快)2)使類構造函數盡可能輕量使用類初始化列表Color() : red(1), blue(2) {}而非初始化函數Color() {red=1;blue=2;} 3)類優先使用+= ,-= ,*= , /=;而非+ ,– , * ,/后者需創建匿名臨時中間變量基本數據類型+ ,– , * ,/而非+= ,-= ,*= , /=;4)對象優先使用前綴操作符(不需拷貝)而非后綴操作符obj++(需一個臨時拷貝)5)類繼承必須有虛析構函數如類析構函數是非虛的,意味著它不會作為基類來使用(這種類就是“實體類”)當您刪除這樣一個對象時,C++將不會調用整個析構鏈;結果是不確定的。不應該公開繼承實體類(STL容器,string,complex)class A{public:~A(){}}; // non virtualclass B: public A {public:~B(){}}; // 不好; A沒有虛析構函數int main(){A * p = new B; delete p;} // 問題出現, B的析構未被調用6)將嵌套類聲明為其包含類的友元嵌套類聲明為外部類的友元類似應當放在后面而不是前面。若友元聲明放置于嵌套類聲明之前將丟棄友元聲明,因為編譯器還沒有見過它class A {private:int i;public: class B{public:B(A & a) { a.i=0;};}; //先定義嵌套類friend class B; //友元聲明}; 7)自定義類的輸出流 見實例38)類成員指針: 見實例4成員指針:成員函數指針和數據成員指針只需要在星號之前加上類名::即可可以使用一個數據成員指針來監測和修改數據成員的值,而不必知道它的名字9)盡量在何時的場合使用單例使用單例可以減輕加載的負擔,縮短加載時的時間,提高加載的效率并不是所有的地方都適用于單例,主要用于以下三個方面:(1) 控制資源的使用,通過線程同步來控制資源的并發訪問;(2) 控制實例的產生,達到節約資源的目的;(3) 控制數據的共享,在不建立直接關聯的條件下,讓多個不相關的進程或線程之間實現通信?3.資源管理
3.1.主要資源包括內存(堆或棧);磁盤網絡文件;網絡連接;線程鎖定時器事務;其他操作系統資源如GDI句柄;易產生資源泄漏3.2.在棧上分配內存void foo(){ResType resource;resource.bar();}//資源都可安全釋放 3.3.資源申請即初始化構造時獲得析構時釋放或基于范圍的資源釋放一般不需要重新造輪子也不需這中包裝器,其實他就是智能指針//使用于不同資源的簡單模板類class Resource {private:int x{ 0 };public:void foo() { cout << x << endl; }};template<typename Resource>class WrapperResource final {public:WrapperResource() { ptr_resource = new Resource(); }~WrapperResource() { delete ptr_resource; }Resource* operator->()const { return ptr_resource; }private:Resource* ptr_resource;};int main(){WrapperResource<Resource> a;a->foo();}3.4.智能指針
1) 具有獨占性智能指針unique_ptr<T>如超出ptrResource作用域,ptrResource釋放其所持有的ResourceType類型實例最好將ptrResource放入容器中不會發生ResourceType實例深拷貝//實例1.1:使用#include<memory>class ResType{};std::unique_ptr<ResType> ptrResource{std::make_unique<ResouceType>()};auto ptrResource{std::make_unique<ResType>()};//使用類型推斷方式更簡單ptrResource->foo();//實例1.2:放入容器using ResTypePtr=std::unique_ptr<ResType>;using ResVecType=std::vector<ResTypePtr>;ResTypePtr resource{std::make_unique>ResType>()};ResVecType vec;vec.push_back(std::move(resource));//分別調用unique_ptr<T>的移動構造函數和移動賦值操作注意:運行到這里時候resource實例變成空//實例1.3:禁調用unique_ptr拷貝構造函數,用move將unique_ptr持有資源轉移給另一個unique_ptrunique_ptr<ResType> pointer1=std::make_unique<ResType>();unique_ptr<ResType> pointer2;//此時是空的pointer2=std::move(pointer1);//此時pointer1是空的,pointer2是持有者?
2)具有所有權的shared_ptr<T>說明:是可拷貝的也可用move<T>來移動他所指向的資源用途: 1)用途1刪除內存中不在使用sharted_ptr.在使用緩存對象地方,weak_ptr的實例用于指向這些對象,但不擁有對象所有權,如weak_ptr<T>實例的expired()返回true那么垃圾回收該對象。2)可用weak_ptr<T>::lock()獲取shared_ptr<T>實例,即使垃圾回收進程處于活動狀態也可安全使用這個對象3)另外一個用途解決循環依賴問題//實例2.1:shared_ptr<T> p1=make_shared<T>();shared_ptr<T> p2;p2=move(p1);T * p=p2.get();//獲取原始指針//實例2.2:如需要一沒有所有權指針用weak_ptr<T>它對資源生命周期沒有影響,僅觀察它所指向資源并檢查該資源是否有效void foo(cost weak_ptr<T>& weakResourse){if(!weakResourse.expired())//資源是有效的shared_ptr<T> sharedResourse=weakResourse.lock(); //獲取一個shared_ptr<T>的實例}int main(){auto sharedResource(make_shared<T>());weak_ptr<T> weakResourse(sharedResource);foo(weakResource);sharedResource.reset();//刪除sharedResource指向的T的實例foo(weakResource); //僅在一小段時間內將弱指針提升為強指針就足夠}3.實例:?
實例1://信息隱藏較差代碼class AutomaticDoor{public:enum class State{closed=1,opening,open,closing};private:State state;public :State getState()const;};int main{}{AutomaticDoor door;AutomaticDoor::State doorsState=door.getState();if(doorsState==AutomaticDoor::State::closed){}}//良好代碼class AutomaticDoor{public:bool isClosed()const;bool isOpening()const;bool isOpen()const;bool isClosing()const;private:enum class State{close=1,opening,open,closed};State state;};int main{}{AutomaticDoor door;if(door.isClosed()){}} 實例2://低內聚class Lamp{//燈和開關是緊耦合public:void on(){}void off(){}};class Switch{private:Lamp& lamp;bool state{false};public:Switch(Lamp& lamp):lamp(lamp){}void toggle(){if(state){state=false;lamp.off();}else{state=true;lamp.on();}};//高內聚低耦合-這個設計對擴展是開放的松耦合關鍵是接口,接口聲明為公共行為而不涉及該類的具體實現//抽象接口:class Switchable{public:virtual void on()=0;virtual void off()=0;};//優點Switch已完全獨立于由他控制的具體類,可進行獨立性測試class Switch{private:Switchable& switchable;bool state{false};public:Switch(Switchable& switchable):switchable(switchable){}void toggle(){if(state){state=false;switchable.off();}else{state=true;switchable.on();}}};//Lamp類實現定義Switchable接口class Lamp:public Switchable{public:void on() override{}void off() override{}}; 實例3://自定義類的輸出流class Box{private:int x;public:friend std::ostream& operator<<(std::ostream& outstream,const Box& box);};std::ostream& operator<<(std::ostream& outstream,const Box& box){ outstream<<box.x<<"\n"<<endl;return outstream;} 實例4:類成員指針訪問成員變量成員函數class A {public:int x=1; int y=2;int add() {return x+y;}};int main(){//成員變量指針:int A::* pv = &A::x;//定義類A成員變量指針A a;assert(a.x == a.*pv);a.*pv = 10; assert(a.x == 10);pv = &A::y; //指向成員變量yassert(a.y == a.*pv);a.*pv = 20; assert(a.y = = 20);A* pA = new A;assert(pA->*pv == pA->y);assert(pA->*pv == 2);pA->*pv = 30; assert(pA->*pv == 30);//成員函數指針:int (A:: * pfunc) ();pfunc = &A::add; //成員函數指針assert(a.x == 10 && a.y == 20);cout<<(a.*pfunc)()<<endl; //30 assert(pA->x == 1 && pA->y == 30);cout << (pA->*pfunc)() << endl;//31delete pA; pA = nullptr;}?
總結
以上是生活随笔為你收集整理的C++编程原则1 tcy的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玉米面菜团子+开花茄子-实作图片
- 下一篇: Linux中启用和禁用网卡