<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
類的基本思想是資料抽象和封裝。
資料抽象是依賴介面和實現分離的程式設計技術。
Sale_data s1; Sale_data s2=s1;//s2拷貝了s1的成員
class A{ //定義了一個實參為string的建構函式 //此時,編譯器不會合成預設建構函式 A(std::string a){} } A a;//錯誤,沒有預設建構函式 A a1(std::string("小黑"));//只能用string引數
=defualt
可以和宣告一起出現在類內,也可以作為定義出現在類外。若在類內部,則預設建構函式時內聯的,若在類外部,預設不是內聯的。
class A{ A()=defualt; } A a;//正確,編譯器生成預設建構函式
::bookNo(s
))class Sales_data{ Sales_data(const std::string &s,unsigned n,double p): bookNo(s),units_sold(n),revenue(p*n){} //當編譯器不支援類內初始值時,可用如下方法定義 Sales_data(const std::string &s): bookNo(s),units_sold(0),revenue(0){} }
類名::
Sales_data::Sales_data(std::istream cin){ read(cin,*this); }
public說明符後的成員在整個程式內可以被存取
private說明符後的成員可以被類的成員函數存取
接下來介紹:型別成員、類的成員的類內初始值、可變資料成員、內聯成員函數、從成員函數返回*this
、如何定義使用類型別、友元類
在類中定義的型別名字和其他成員一樣存在存取限制,可以是public或者private
類別名必須先定義後使用
(回憶:類成員變數可以在類成員函數之後定義,但是在類函數中使用,原因是編譯器先編譯類成員變數後邊一類成員函數)
型別成員通常出現在類開始的地方
class Screen{ public: //等價於 using pos = std::string::size_type typedef std::string::size_type pos; }
定義在類內部的函數是自動inline的,定義在類外部的函數,若需要宣告行內函式,要加上inline;inline成員函數也應該和相應的類定義在同一個標頭檔案夾
inline Screen& Screen::move(pos r,pos c){ pos row = r*width; cursor = row + c; return *this; }
class Screen{ public void some_member() const; private: mutable size_t access_ctr;//使用mutable宣告可變資料成員 } void Screen::some_member() const { ++access_ctr;//即使在const成員函數中,仍然可以修改可變資料成員 }
inline Screen &Screen::set(char ch){ content[cursor] =ch; return *this; } inline Screen &Screen ::move(pos r,pos col){ cursor= r * width + col ; return *this; } Screen s(3,2,''); //move函數返回s本身,所以可以接著呼叫set函數 //並且move函數返回的是Screen的參照,若返回的不是參照,則會返回一個新的Screen物件 s.move(3,2).set('!');
編寫函數display列印Screen中的contents,因為只是展示,不需要修改值,所以這應該是一個const函數。
但是希望實現在展示後,能移動遊標:s.display().move(2,3)。這要求display返回的值是可以修改的,所以這不應該是const函數。
基於const過載,可以根據Screen物件是否是const來進行過載。
class Screen{ public: Screen* display(std::ostream &os){ do_display(os); return *this; } const Screen* display(std::ostream &os) const{ do_display(os); return *this; } private: void do_display(std::ostream &os) const{ os<<content; } } int main(){ const Screen cs(3,3,'!'); Screen s(3,3,'.') cs.display();//因為cs是const的,呼叫第二個const函數 s.display();//呼叫第一個非const的函數 }
class A{ int member; } class B{ int member; } A a; B b = a;//錯誤!!
有一個screen類,有私有成員content;
有clear函數,可以清除content的內容。
1.先宣告clear函數
2.在screen類中將clear函數函數定義為友元函數
3.定義clear函數,使用screen類
有類window,window有私有成員content;友元類 window_mgr需要直接操作content。
#ifndef xxx_H #define xxx_H /class 定義/// #endif
struct X{ friend viod f(){/*友元函數可以定義在類的內部,但是我認為這樣沒有意義*/ X(){f();}//錯誤,f還沒有被定義 void g(); void h(); } void X::g(){ return f();}//錯誤,f還沒有被定義 void f(); void X::h(){return f();}//正確,f的宣告已經在定義中了 };
//pos的型別宣告在window類中,並且返回型別在類的作用域外,因此要使用window::pos window::pos window::get_pos(){ //在window::get_pos後的所有程式碼作用域在類內,所以返回cursor,相當於this->cursor return cursor; }
typedef double Money; class Acount{ public: Money balace(){return bal;}//使用外層定義的Money private: typedef double Money;//錯誤,不能重新定義Money Money bal; }
double height; class Window{ double height; } void Window::dummy_fcn(double height){ double class_height = this->height; double para_height = height; double global_height = ::height; }
//範例危險操作 strcut X{ //實際上按照宣告順序初始化,先初始化rem時,base的值未知 X(int i,int j):base(i),rem(base%j){} int rem,base; }
class Sale_data{ public: Sales_data(const std::string &s,unsigned s_num,double price):units_sold(s_num),revenue(s_num*price),BookNo(s){} Sales_data():Sales_data("",0,0){}//委託給上一個建構函式 }
1.塊作用域內不使用任何初始值定義的一個非靜態變數或者陣列時
2.類本身含有類型別的成員且使用合成的預設建構函式
3.類型別成員沒有在建構函式初始值列表中顯式初始化時
1.初始化陣列時,提供的初始值數量少於陣列大小
2.不使用初始值定義一個區域性變數時
3.書寫形如T()的表示式顯式請求值初始化時,其中T是型別名。如vector接受一個實參說明vector的大小
vector<string> str_vec; //需要push一個string,但傳參一個字串。這裡使用了string的轉換建構函式 str_vec.push_back("小黑~");
//Sales_data有引數為string的建構函式 //Sales_data的combine為方法: //Sales_data & Sales_data::combine(const Sales_data& ); Sales_data item; item.combine("無限~")//錯誤,只允許一步構造 item.combine(string("無限~"))//正確,只有string到Sales_data的一步隱式構造轉換
explicit
抑制建構函式定義的隱式轉換class Sales_data{ explicit Sales_data(const string&):bookNo(s){}; ...//其他宣告 } item.combine(string("無限~"));//錯誤,explicit阻止了隱式轉換
explicit
函數只能用於直接初始化
//Sales_data的建構函式:explicit Sales_data(const string&):bookNo(s){}; string bookNo = "001"; Sales_data item1(bookNo);//正確,直接初始化 Sales_data item2 = bookNo;//錯誤,拷貝初始化
儘管編譯器不會將explicit
的建構函式用於隱式轉換過程,但是可以使用顯式強制轉化
string bookNo ="001"; item.combine(bookNo);//錯誤,explicit阻止了隱式轉換 item.combine(static_cast<Sales_data>(bookNo));//正確,強制轉換
1.所有成員都是public的
2.沒有定義任何建構函式
3.沒有類內初始值
4.沒有基礎類別,也沒有virtual函數
class Data{ public: int ival; string s; } //順序一定相同 Data val1={0,"孔子"};
1.資料成員都是字面值型別
2.類必須含有一個 constexpr建構函式
3.使用預設定義的解構函式
4.如果一個資料成員含有類內初始值,則該初始值必須是一條常數表示式;如果資料成員屬於某種類型別,則初始值必須使用自己的constexpr建構函式
class Data{ public: constexpr Data(int para_i,string para_s):ival(para_i),s(para_s){} int ival; string s; } constexpr Data data(1,"吃烤肉");
class Bar{ public: //... provite: static Bar mem1;//正確,static成員可以是不完整型別 Bar* mem2;//正確,指標成員可以是不完整型別 Bar mem3;//錯誤 }
- 靜態成員可以作為預設實參
class Screen{ public: Screen& clear(char = bkground) private: static const char bkground; }
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45