程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 類 - 3C++ Primer 學習筆記

類 - 3C++ Primer 學習筆記

編輯:C++入門知識

[cpp]
class Sale_item 

public: 
    // 隱式使用string 的默認構造函數初始化 isbn 
    Sale_item():price(0.0){}     
 
    Sale_item(const string &book):isbn(book), price(0.0){} 
 
    // 建議使用默認實參,將上述2個構造函數合並。如下: 
    // Sale_item(const string &book = ""):isbn(book), price(0.0){} 
private: 
    string isbn; 
    double price; 
}; 

合成的默認構造函數
如果,類沒有定義構造函數,編譯器將會自動生成一個默認的構造函數。
但是,如果已經定義過構造函數(哪怕只有1 個), 編譯器就不會再生成默認構造函數。
理由:因為一個類,在某種情況下,需要控制對象的初始化,則,該類很可能在所有情況下都需要控制。

合成的默認構造函數,的初始化規則,與變量的初始化規則相同。
類類型,使用各自的默認構造函數,來初始化
內置、復合類型,如:指針、數組,只對定義在全局作用域中的對象才初始化,
定義局部作用域中,則,內置、復合類型不初始化,處於未定義狀態。

類通常,都應該定義一個默認構造函數

假設:NoDefault ,是一個類,它具有接受一個 string 實參的構造函數,
這種情況下,編譯器,不會生成默認構造函數。
於是,
1、當我定義一個類 A,具有 NoDefault 類型的成員,則,
A 的所有構造器,都必須通過傳遞一個初始 string 來初始化 NoDefault 類型的成員

2、當我定義一個類 A,具有 NoDefault 類型的成員,則,
編譯器將不會生成 A 的默認構造器。只能自己顯示定義

3、NoDefault 類型,不能用作動態分配數組的元素類型。
[cpp]
int *iArr = new int[10]; 
 
// 上式可行,下式報錯 
NoDefault *arr = new NoDefault[10]; 

4、NoDefault 類型的靜態分配數組,也必須為每個元素提供顯示的初始化
5、如果有保存 NoDefault 對象的容器,如:vector,
則,容器的構造函數,不僅要提供容器大小,也要提供元素初始化式。


[cpp]
// 這是一個函數聲明,函數返回類型:Sales_item 
Sales_item myObj(); 
 
//  
Sales_item myObj2; 
 
// 創建一個 Sales_item 對象,並用默認構造函數初始化 
Sales_item myObj3 = new Sales_item(); 


隱式類型轉換
[cpp] 
class Sales_item 

public: 
 
    Sales_item(const string &book = ""):isbn(book), units_sold(0), revenue(0.0){}    
    // explicit 只能用於,類內部的構造函數聲明上,在類的定義體外部則不用重復它 
    explicit Sales_item(istream &is); 
    Sales_item(); 
 
    bool same_isbn(Sales_item item) 
    { 
        return item.isbn == isbn; 
    } 
private: 
    string isbn; 
    int units_sold; 
    double revenue; 
}; 
// 錯誤: explicit 只能在類內部的構造函數聲明上 
explicit Sales_item::Sales_item(istream &is) 

    /* ... */ 

 
/* ... */ 
string null_book = "9-999-9999-9"; 
Sales_item item_a = Sales_item("1-111-1111-1"); 
 
// 以下會隱式調用構造函數,生成一個 Sales_item 對象,來進行比較 
// 但這種隱式轉換,未必是我們真正想要的。 
// 為阻止這種隱式轉換,可以在構造函數前,使用 explicit 關鍵字 
item_a.same_isbn(null_book); 
 
// 建議使用下面的方式,避免錯誤 
item_a.same_isbn(Sales_item(null_book)); 


[cpp] 
// 沒有定義構造函數、並且,全體數據成員都是 public 的類, 
// 可以采用,與數組元素相同的方式,來初始化成員 
// 但,還是推薦,使用構造函數 
struct Data 

    int ival; 
    char *ptr; 
}; 
Data val1 = {0, 0}; 


友元,允許一個類,將自己的,非公有成員的訪問,授權給,指定的類或者函數。
它只能出現在類定義的內部。通常,將所有的友元聲明,成組地放到類定義的開始或者結尾。

[cpp]
class Screen 

public: 
    typedef string::size_type index; 
private: 
    int height; 
    int width; 
 
    // 友元不是 Screen的成員, 
    // 它可以出現在 Screen 類定義體中的,任何地方。 
    // 並且,不受訪問控制(private、public)的影響 
    friend class Window_Mgr; 
 
    // 將,其他類的成員函數,設置為友元 
    friend Window_Mgr& Window_Mgr::relocate(Screen::index, Screen::index, Screen&);  
}; 
class Window_Mgr 

public: 
    Window_Mgr& relocate(Screen::index r, Screen::index c, Screen &s) 
    { 
        s.height += r; 
        s.width += c; 
        return *this; 
    } 
private: 
 
}; 


要將類的成員函數,設為友元,則這個類必須先定義
要將類 或者 非成員函數 設為友元,則,不需要預先聲明。
(P398,例子,貌似有誤)

全局對象,會破壞封裝性,而,類中定義的 靜態成員,則能保持很好的封裝性。
static 數據成員,與類相關聯,而不是與類的對象關聯。
static 成員函數,沒有 this 形參。
[cpp] 
class Account 

public: 
    void applyint(){ amount += amount * interestRate; } 
    static double rate() { return interestRate; } 
    static void rate(double); 
     
private: 
    string owner; 
    double amount; 
    static double interestRate; 
    static double initRate(); 
 
    // 例外,const 類型的靜態數據成員,可以在類定義體中初始化 
    // 但是,即使如此,也必須在外部,進行定義 
    static const int period = 30; 
}; 
// 外部定義,但此時,無須提供初始化式 
const int Account::period; 
 
// 內部已經聲明為 static 了 
// 外部定義的時候,不需要再指定 static 
// static 不能聲明為 const、也不能聲明為 虛函數 
// 聲明為 const 是承諾不修改該函數所屬的對象, 
// 然而, static 函數,不屬於任何對象,它只與類關聯 
void Account::rate(double newRate) 

    interestRate = newRate; 

 
// static 數據成員,必須在類定義體的外部定義(剛好一次) 
// 一旦成員名出現,static 成員的定義,就在類作用域中了 
// 因此,可以直接使用 私有成員函數 initRate 
double Account::interestRate = initRate(); 
Account ac1; 
Account *ac2 = &ac1; 
double rate; 
rate = ac1.rate(); 
rate = ac2->rate(); 
rate = Account::rate(); 

[cpp] 
class Bar 

public: 
private: 
    // static 數據成員的類型,可以是該成員所屬的類類型。 
    static Bar mem1; 
    Bar *mem2; 
 
    // 錯誤 
    Bar mem3;    
}; www.2cto.com
class Screen 

public: 
    Screen& clear(char = bkground); 
private: 
    // static 數據成員,可以作為默認實參。 
    static const char bkground = '#'; 
}; 


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved