国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

c++教程(二十: Friendship and inheritance)

2019-11-10 23:28:23
字體:
供稿:網(wǎng)友

Friend functions

原則上講,一旦一個類被聲明以后,那么這個類內(nèi)部的私有與保護(hù)(PRivate and protected)成員就不可以被這個類以外的其他函數(shù)所訪問。然而這一條準(zhǔn)則對于友元類來說不適用。

友元的類或者函數(shù)的聲明使用關(guān)鍵字“friend”。

被一個類聲明了“friend”以后,那么不是該類的成員函數(shù)也可以訪問類的私有有被保護(hù)成員。 這可以通過在類里面使用一個額外的函數(shù)通過關(guān)鍵字friend來聲明。

// friend functions#include <iostream>using namespace std;class Rectangle { int width, height; public: Rectangle() {} Rectangle (int x, int y) : width(x), height(y) {} int area() {return width * height;} friend Rectangle duplicate (const Rectangle&);};Rectangle duplicate (const Rectangle& param){ Rectangle res; res.width = param.width*2; res.height = param.height*2; return res;}int main () { Rectangle foo; Rectangle bar (2,3); foo = duplicate (bar); cout << foo.area() << '/n'; return 0;}

上述中duplicate 函數(shù)就是類Rectangle的一個友元類。因此函數(shù)duplicate 是可以訪問成員width和height的(雖然這兩個參數(shù)是類Rectangle的私有變量)。注意的是,類duplicate中既沒有聲明也不包含,但是在main函數(shù)中是可以使用的。函數(shù)duplicate被認(rèn)為是類Rectangle的一個成員?其實不是的,它只是可以訪問類Rectangle的私有與被保護(hù)的變量而已。

友元函數(shù)的典型用例是在兩個不同的類之間訪問私有或受保護(hù)成員的操作。

Friend classes 友元類

同友元函數(shù)類似,友元類是一種可以訪問其他類的私有與保護(hù)成員的一種類型。

// friend class#include <iostream>using namespace std;class Square;class Rectangle { int width, height; public: int area () {return (width * height);} void convert (Square a);};class Square { friend class Rectangle; private: int side; public: Square (int a) : side(a) {}};void Rectangle::convert (Square a) { width = a.side; height = a.side;}int main () { Rectangle rect; Square sqr (4); rect.convert(sqr); cout << rect.area(); return 0;}

在這個例子中,類Rectangle 就是類Square 的一個友元類,所以Rectangle的成員函數(shù)就可以訪問Square的私有與保護(hù)的成員變量。更準(zhǔn)確的說,Rectangle 訪問了類Square 中的變量Square::side,而這個變量只在類square中被定義過。

在這個例子中也有一些值得注意的:在程序的開頭,需要對類Square進(jìn)行一個空的聲明。這一點(diǎn)是必須的,因為類Rectangle會用到類square(在函數(shù)convert中作為參數(shù)使用),并且Square 使用了Rectangle (作為友元的聲明)。

除非特別聲明,否則友元關(guān)系不是對應(yīng)的。在我們這個例子中,Rectangle 被認(rèn)為是Square的友元,但是Square并不認(rèn)為是Rectangle 的友元。因此,Rectangle 中的函數(shù)可以使用Square中的私有與保護(hù)的成員,但是反過來就不行。當(dāng)然,如果Rectangle 中也可以聲明Square為友元,這樣的話就可以使用了。

友元的另一個屬性是他們的這種關(guān)系并不能夠傳遞,也就是說友元的友元并不是友元除非特別聲明。

類間的繼承

C++中的類可以擴(kuò)展,創(chuàng)建新類保留基類的特性。這個過程稱為繼承,它包含基類和派生類:派生類繼承基類的成員,在此基礎(chǔ)上它可以添加自己的成員。

例如,讓假設(shè)有一系列的類來描述兩種多邊形:矩形和三角形。這兩個多邊形具有一定的共同屬性,如計算其面積的值:它們都可以簡單地描述為高度和寬度(或基本屬性)。

這可以用一個類多邊形來表示,我們將得到另外兩個類:矩形和三角形:

這里寫圖片描述

多邊形類將包含兩種類型的多邊形的成員。在我們的例子中就是寬度和高度。矩形和三角形是其派生類,具有不同于一類多邊形到另一類的特殊特征。

派生的類可以繼承基類的所有可訪問成員。這意味著,如果一個基類包含一個成員A,并且我們從它中派生一個類,而另一個成員稱為B,派生類將包含成員A和成員B.。

派生類中聲明了兩個類的繼承關(guān)系。派生類的定義使用下列語法:

class derived_class_name: public base_class_name{ /*...*/ };

這里derived_class_name是派生類,base_class_name是基類。公共訪問說明符public可以由其他訪問說明符任何一個取代(protected或private)。從基類繼承的成員的訪問說明符可以限制繼承基類成員的訪問權(quán)限:和基類訪問水平接近的繼承成員就用這個水平代替,而在派生類中與同等或更嚴(yán)格的訪問級別保持他們的限制級別的成員。

// derived classes#include <iostream>using namespace std;class Polygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b;} };class Rectangle: public Polygon { public: int area () { return width * height; } };class Triangle: public Polygon { public: int area () { return width * height / 2; } };int main () { Rectangle rect; Triangle trgl; rect.set_values (4,5); trgl.set_values (4,5); cout << rect.area() << '/n'; cout << trgl.area() << '/n'; return 0;}

類的對象矩形和三角形都包含從多邊形繼承的成員。這些是:寬度、高度和set_values。

多邊形的類說明符protected訪問類似于private。對于繼承來說,這兩者的唯一區(qū)別在于:當(dāng)類繼承另一個類時,派生類的成員可以訪問從基類繼承的受保護(hù)成員,而不是訪問其私有成員。

通過聲明寬度和高度作為protected 而非private,使得這些成員也可以從派生類矩形和三角形中獲得,而不僅僅是來自多邊形成員。如果他們是 public,他們可以從任何地方訪問。

我們可以根據(jù)功能總結(jié)不同的訪問類型,可以訪問它們的方式如下:

這里寫圖片描述

“not members”表示類外的任何訪問,例如從主體、從另一個類或從函數(shù)。

在上面的示例中,矩形和三角形所繼承的成員具有相同的訪問權(quán)限,因為它們在基類多邊形中具有相同的訪問權(quán)限:

Polygon::width // protected accessRectangle::width // protected accessPolygon::set_values() // public accessRectangle::set_values() // public access

這是因為繼承關(guān)系已在每個派生類中使用public關(guān)鍵字聲明:

class Rectangle: public Polygon { /* ... */ }

這個冒號(:)后的public關(guān)鍵字表示從繼承的類中繼承的成員的最易訪問級別 (在這種情況下,多邊形)將來自派生類(在這種情況下,矩形)。由于公共是最容易訪問的級別,通過指定關(guān)鍵字,派生類將繼承基類中具有相同級別的所有成員。

通過protected,基類的所有公共成員在派生類中繼承為受保護(hù)的protected 。相反,如果指定了最受限制的訪問級別(private),所有基類成員都將繼承為私有。

例如,如果女兒是來自母親的類,我們定義為:

class Daughter: protected Mother;

Daughter將被protected為較少限制的訪問級別的,它繼承于Mother。也就是說,所有在Mother公開的成員都會在Daughter身上得到保護(hù)。當(dāng)然,這不會限制Daughter聲明的自己的public成員。只為從Mother繼承的成員設(shè)置較少限制訪問級別。

如果繼承沒有指定訪問級別,編譯器就會為類class假定為private 的類聲明關(guān)鍵字,同時會為struct結(jié)構(gòu)體聲明為public的類關(guān)鍵字。

實際上,在C++大多數(shù)用例繼承應(yīng)該使用public繼承。當(dāng)基類需要其他訪問級別時,通常可以更好地表示為成員變量。

從基類繼承的是什么?

原則上,公開派生類繼承了對基類的每個成員的訪問,除了:

(1)它的構(gòu)造函數(shù)和析構(gòu)函數(shù) (2)賦值操作符成員(運(yùn)算符=) (3)它的友元 (4)它的private 私有成員

即使基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能繼承等,派生類的析構(gòu)函數(shù)和構(gòu)造函數(shù)也會自動調(diào)用。

除非另有說明,派生類的構(gòu)造函數(shù)調(diào)用基類的默認(rèn)構(gòu)造函數(shù)(即沒有參數(shù)的構(gòu)造函數(shù))。使用初始化列表中成員變量的相同語法,調(diào)用基類的不同構(gòu)造函數(shù)是可能的:

derived_constructor_name (parameters) : base_constructor_name (parameters) {...}

例如:

// constructors and derived classes#include <iostream>using namespace std;class Mother { public: Mother () { cout << "Mother: no parameters/n"; } Mother (int a) { cout << "Mother: int parameter/n"; }};class Daughter : public Mother { public: Daughter (int a) { cout << "Daughter: int parameter/n/n"; }};class Son : public Mother { public: Son (int a) : Mother (a) { cout << "Son: int parameter/n/n"; }};int main () { Daughter kelly(0); Son bud(0); return 0;}

當(dāng)創(chuàng)建一個新的Daughter對象,當(dāng)它是Daughter對象時,請注意與Mother構(gòu)造函數(shù)的調(diào)用之間的區(qū)別。不同的是由于不同的構(gòu)造函數(shù)聲明的Daughter和Son:

Daughter (int a) // nothing specified: call default constructorSon (int a) : Mother (a) // constructor specified: call this specific constructor

多繼承

一個類可以通過指定多個基類繼承多個類,以逗號分隔,在一個類的基類列表中 (即,冒號后)。例如,如果程序有一個特定的類Output在屏幕上打印輸出,我們希望我們的類Rectangle 和Triangle除了繼承Polygon 也繼承Output的成員我們可以寫:

class Rectangle: public Polygon, public Output;class Triangle: public Polygon, public Output;

完整的例子為:

// multiple inheritance#include <iostream>using namespace std;class Polygon { protected: int width, height; public: Polygon (int a, int b) : width(a), height(b) {}};class Output { public: static void print (int i);};void Output::print (int i) { cout << i << '/n';}class Rectangle: public Polygon, public Output { public: Rectangle (int a, int b) : Polygon(a,b) {} int area () { return width*height; }};class Triangle: public Polygon, public Output { public: Triangle (int a, int b) : Polygon(a,b) {} int area () { return width*height/2; }};int main () { Rectangle rect (4,5); Triangle trgl (4,5); rect.print (rect.area()); Triangle::print (trgl.area()); return 0;}
上一篇:c++知識

下一篇:續(xù)C++ style 筆記

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 电白县| 铜梁县| 松原市| 资中县| 湟中县| 四平市| 曲阜市| 辉县市| 宣武区| 靖安县| 汉中市| 阜新市| 湖口县| 汉寿县| 高阳县| 昌江| 岗巴县| 咸丰县| 西林县| 鸡西市| 久治县| 邹城市| 伊吾县| 柳林县| 米泉市| 时尚| 连云港市| 布尔津县| 南木林县| 师宗县| 府谷县| 利川市| 孝感市| 海伦市| 湖州市| 屏东市| 屏东市| 屏东市| 延边| 山东| 旬阳县|