1. 程式人生 > >類的認識(二)

類的認識(二)

一.const成員函式

const int a=10;
int b=a;

我知道const修飾的變數具有隻讀屬性,a具有隻讀屬性,不能修改直接通過a修改a,而b則可讀可寫。

int a=30;
const int*p=&a;

這裡的const修飾的是指標變數*p,限定定義指標所指向位置的內容*p,不允許*p=50,可以改變的是指標所指向的位置p。允許p=&b

int a=30;
int*const p=&a;

此時,const修飾p,即就是指標變數p只讀,指標指向位置被限定不允許p=&b,指標所指向的位置的內容可以改變允許*p=50

也就是p對比你會發現,僅僅是const和*的前後位置不同了而已。

上述複習了const修飾變數的用法,接下來我們看一下這段程式碼:

Time operator+(const Time &t) const
	{
		Time t1 = (*this);
		Time t2 = t;
		t1._minute += t2._minute;
		t1._minute += t2._minute;
		t1._second += t2._second;
		while (!(t1._second < 60))
		{
			t1._second -= 60;
			t1._minute += 1;
		}
		while (!(t1._minute <
60)) { t1._minute -= 60; t1._hour += 1; } while (!(t1._hour < 24)) t1._hour -= 24; return t1; } void Show()const { cout << _hour << ':' << \ _minute << ':' << _second << ':' << endl; }

在成員函式後面加const,const修飾this指標所修飾的物件,也就是保證這個const成員函式的物件在函式體內不會被改變。
重點思考:


const物件不可以呼叫非const成員函式,非const物件可以呼叫const成員函式。
const成員函式不可以呼叫其它非const成員函式,非const成員函式可以呼叫其它的const成員函式。

二.行內函數

以inline修飾的函式叫做行內函數,編譯時C++編譯器會在呼叫行內函數的地方展開行內函數。省去函式壓棧的開銷,以空間換時間的做法。
1、**inline必須和函式定義放在一起才能成為行內函數,**僅將inline放在宣告前不起作用。
2、inline對編譯器來說只是建議,並非指令,編譯器會自行優化。
3、定義在類內的成員函式,預設為行內函數。
4、程式碼很長或者有迴圈或者遞迴不適宜使用行內函數。

inline void Show()
	{
		cout << _hour << ':' << \
		_minute << ':' << _second << ':' << endl;
	}

三.友元

友元類
整個類是另一個類的友元。友元類的每一個成員函式都是另一個類的友元函式,都可以訪問另一個類的保護或者私有資料成員。

class Time{
	friend class Date;
private:
	int _hour;
	int _minute;
	int _second;
};
class Date{
public:
	void Display()
	{
		cout << _year << ":" <<\
		 _month << ":"\
		  << _day << ":" \
		  << _t._hour << ":" \
		  << _t._minute << ":" \
		  << _t._second << endl;
	}
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

友元類在一定程度上破壞了C++的封裝性,應該儘量少用。

友元函式

友元函式允許類外訪問該類的任何成員,就像成員函式一樣,友元函式用關鍵字friend說明。
1、友元函式不是類的成員函式。
2、友元函式可以通過訪問所有成員,私有和保護也一樣。

#include<iostream>
#include<assert.h>
using namespace std;

class Time{
public:
	friend void Show(const Time&d);

	Time(const int hour = 23, const int minute = 59, const int second = 59)
		:_hour(hour)
		, _minute(minute)
		, _second(second)
	{
		if (!Islegal(_hour, _minute, _second))
			assert(0);
	}
	Time(const Time&t)
		:_hour(t._hour)
		, _minute(t._minute)
		, _second(t._second)
	{
	}
	
	~Time()
	{}
private:
	bool Islegal(int&hour, int&minute, int&second)
	{
		if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
			return true;
		else
			return false;
	}
	int _hour;
	int _minute;
	int _second;
};

void Show(const Time&d)
{
	cout << d._hour << ':' << 
		d._minute << ':' << 
		d._second << ':' << endl;
}
int main()
{
	Time t1;
	Show(t1);
	system("pause");
	return 0;
}

這裡我們試著過載一下Time類的cin、cout

#include<iostream>

using namespace std;

class Time{
	int _hour;
	int _minute;
	int _second;
	
public:
	
	friend ostream& operator<<(ostream&out, const Time&t)
	{
		out << t._hour<<":" << t._minute <<":"<< t._second << endl;
		return out;
	}
	friend istream& operator>>(istream&in, Time&t)
	{
		cout << "請輸入年月日:" << endl;
		in >> t._hour;
		in >> t._minute;
		in >> t._second;
		return in;
	}
};

int main()
{
	Time t1;
	cin >> t1; 
	cout << t1;
	system("pause");
	return 0;
}

這裡寫圖片描述

四.static成員

類的靜態成員
1、類裡邊static修飾的成員,稱為靜態成員。
2、類的靜態成員是該類的所有物件所共享。

靜態成員函式
靜態成員函式與普通成員函式的區別:
1、靜態成員函式沒有 this 指標,只能訪問靜態成員(包括靜態成員變數和靜態成員函式)。
2、普通成員函式有 this 指標,可以訪問類中的任意成員;而靜態成員函式沒有 this 指標。

#include <iostream>
using namespace std;

class Cpoint{
    public:
        static int value;
        static int num;
    Cpoint(int x,int y){
        xp=x;yp=y;
        value++;
        cout << "呼叫構造:" << value << endl;
    }

    ~Cpoint(){num++; cout << "呼叫析構:" << num << endl;}

    private:
    int xp,yp;
};

int Cpoint::value=0;
int Cpoint::num=0;
class CRect{
    public:
        CRect(int x1,int x2):mpt1(x1,x2),mpt2(x1,x2) {cout << "呼叫構造\n";}
        ~CRect(){cout << "呼叫析構\n";}
    private:
        Cpoint mpt1,mpt2;
};

int main()
{
    CRect p(10,20);
    cout << "Hello, world!" << endl;
    return 0;
}

五.N中構造拷貝構造的優化

#include<iostream>  
using namespace std;  
  
class Date  
{   
public :  
    Date()  
    {  
        cout<<"Date()" <<endl;  
    }  
  
    Date(const Date& d)  
    {  
        cout<<"Date(const Date& d)" <<endl;  
    }  
  
    Date& operator =(const Date& d )  
    {  
        cout<<"Date& operator=(const Date& d)"<< endl;  
        return *this ;  
    }  
  
    ~Date()  
    {  
        cout<<"~Date()" <<endl;  
    }  
};  
  
// 1.Date 物件做引數傳值 & 傳引用  
void fun1 (Date d)   
{}  
  
//void fun1(Date& d)  
//{}  
  
// 2.Date 物件做返回值傳值 & 傳引用  
Date fun2 ()   
{  
    Date d ;  
    return d ;  
}   
  
//Date& fun2()  
//{  
//  Date d ;  
//  return d ;  
//}  
  
// 3.Date 物件做臨時返回值傳值 &傳引用(編譯器優化問題)  
Date fun3 ()   
{  
    return Date ();  
}  
  
//Date& fun3()  
//{  
//  return Date ();  
//}  
  
void Test1()  
{  
    Date d1;  
    fun1(d1);  
}  
  
void Test2()  
{  
    Date d2 = fun2();  
}  
  
void Test3()  
{  
    Date d3;  
    d3 = fun3();  
}  

Test1

這裡寫圖片描述
Test2

這裡寫圖片描述
Test3

這裡寫圖片描述

題目:

Test1中呼叫了___次AA的拷貝建構函式,___次AA的賦值運算子函式
的過載。 
Test2中呼叫了___次AA的拷貝建構函式,___次AA的賦值運算子函式
的過載。 
Test3中呼叫了___次AA的拷貝建構函式,___次AA的賦值運算子函式
的過載。 
class AA 
{}; 
AA f (AA a) 
{ 
 return a ; 
} 
void Test1 () 
{ 
 AA a1 ; 
 a1 = f(a1); 
} 
void Test2 () 
{ 
 AA a1 ; 
 AA a2 = f(a1); 
} 

void Test3 () 
{ 
 AA a1 ; 
 AA a2 = f(f(a1)); 
} 

這裡寫圖片描述

相關推薦

認識

一.const成員函式 const int a=10; int b=a; 我知道const修飾的變數具有隻讀屬性,a具有隻讀屬性,不能修改直接通過a修改a,而b則可讀可寫。 int a=30; const int*p=&a; 這裡的const修飾的

c語言數據

nbsp tex 字符 pre 字符串 輸入 mce 一個 命令 char 類型 1.char 變量 常量   char c; 定義一個char變量   c = ‘a’ ‘a‘字符常量   char 的本質就是一個整數,只有一個字節大小的整數 2.printf 輸出ch

python 數據

必須 one set 方式 數據 順序 就是 erro art 一、dict d = { ‘Adam‘: 95, ‘Lisa‘: 85, ‘Bart‘: 59 }查:訪問dict中的元素:d[‘Adam‘]如果dict中Key不存在會報錯:KeyEr

MySQL中的日誌-General query log

sql 設置 set 線程id lob 進行 mysq 示例 mark 簡介 General query log記錄客戶端的連接和斷開,以及從客戶端發來的每一個SQL語句。 日誌內容格式 General query log可以記錄在文件中,也可以記錄在表中,格式如下:在文件

java之進制與數據

bsp bre 進制 3.4 高精度 short ali word 部分 一、各數據類型的最大值和最小值整數:以byte為例,我們知道,byte共有8個bit位,最大值是0111111,最小值是10000000,用十進制來表示就是-128~127,即-2^7~2^7。依照上

python基本數據-python3.0學習筆記

tin 基本數據 abcde 返回 屬性方法 mat sizeof 不可變 map python基本數據類型 序列類型的自帶方法 1.列表的常用方法 2.元祖的常用方法 3.字符串的常用方法 1.列表常用的方法 L.append(obj) #在列表末尾添加新的對

YII1 MVC初認識

end public 靜態頁 意思 好的 assets 如何 sset 還要 上次說了yii1的安裝,這次說下簡單的使用,其實使用看手冊就可以了,我這裏就簡單說下快速調通一個框架,跑通一個helloworld的方法。 1.首先 你得知道 views cont

Linux系統安裝--LInix系隨筆

cfg 工具 拷貝 inux 過多 config 邏輯 虛擬機 數據 2018-07-2917:13:18 ①VMware虛擬機安裝與使用   這裏不再過多的說明。②系統分區 1、磁盤分區:主分區最多4個,擴展分區最多1個,主加擴展分區最多4個。擴展分區:不能寫入

C語言基礎篇-數據關鍵字

至少 硬件 邏輯結構 內存空間 結構 根據 什麽 操作 自定義 導航:   1. 數據類型   2. 自定義類型   3. 邏輯結構   4. 類型修飾符   5. 雜項 ----->x<------------->x<--------------

吳恩達老師機器學習筆記K-means聚演算法

運用K-means聚類演算法進行影象壓縮 趁熱打鐵,修改之前的演算法來做第二個練習—影象壓縮 原始圖片如下: 程式碼如下: X =imread('bird.png'); % 讀取圖片 X =im2double(X); % unit8轉成double型別 [m,n,z]=size

分析k-means及matlab程式

1.介紹 k-means是一種常見的基於劃分的聚類演算法。劃分方法的基本思想是:給定一個有N個元組或者記錄的資料集,將資料集依據樣本之間的距離進行迭代分裂,劃分為K個簇,其中每個簇至少包含一條實驗資料。 2.k-means原理分析 2.1工作原理 (1)首先,k-means方法從資料集中隨機

演算法

密度聚類 密度聚類假設聚類結構能通過樣本分佈的緊密程度確定,通常情況下密度聚類演算法從樣本密度的角度來考察樣本之間的可連線性,並基於可連線樣本不斷擴充套件聚類 簇以獲得最終的聚類結果 DBSCAN 基於一組鄰域引數來刻畫樣本分佈的緊密程度。 事先不用預設聚類簇數

外賣商城app

這一節就主要說說如何實現移動端1px的實現。 為什麼要說這個,就要要說到devicePixelRatio這個東西了。 window.devicePixelRatio是裝置上物理畫素和裝置獨立畫素(dev

深入淺出UML

      關聯(Association)關係是類與類之間最常用的一種關係,它是一種結構化關係,用於表示一類物件與另一類物件之間有聯絡,如汽車和輪胎、師傅和徒弟、班級和學生等等。在UML類圖中,用實線連線有關聯關係的物件所對應的類,在使用Java、C#和C++等程式語言實現關聯關係時,通常將一個類的物件作為另

java反射操作結構

java反射操作類結構 反射操作構造方法 Class只是作為反射的操作源頭,但是嚴格來講,反射還有其他內容。反射給使用者最大的方便有三點: 1.構造呼叫 2.方法呼叫 3.屬性呼叫 在反射機制裡面提供有java.lang.reflect包,包中最重

演算法、聚演算法的系統性比較

      聚類是試圖將資料集中的樣本劃分為若干個不相交的子集。每個子集稱為一個“簇”(cluster)。聚類既能作為一個單獨的過程,也可以作為分類等其他學習任務的前驅任務、例如,在一些商業應用中,需要對新使用者的型別進行判別,但是定義“使用者l型別”對商家來說可不容易,此時

資料探勘演算法之聚分析canopy演算法

canopy是聚類演算法的一種實現 它是一種快速,簡單,但是不太準確的聚類演算法 canopy通過兩個人為確定的閾值t1,t2來對資料進行計算,可以達到將一堆混亂的資料分類成有一定規則的n個數據堆 由於canopy演算法本身的目的只是將混亂的資料劃分成大概的幾個類別,所以它

生成、打包、部署和管理應用程序及

其中 執行c led 包含成員 托管 stat rtu abs top 1 生成、打包、部署和管理應用程序及類型 1.1 .net framework 部署目標 Windows一直不穩定和過於復雜(其實也很封閉,逐漸開放,如core),微軟認為主要原因是: (1)

ssm框架常用jar包認識

11.commons-fileupload-1.2.1.jar Apache的commons-fileupload.jar可方便的實現檔案的上傳功能 一、簡單介紹     使用最為廣泛的Java檔案上傳元件,Struts本身採用這個包來處理檔案上傳。其基本原理: File

三層架構深入認識

1、複用:主要表現在使用者層(UI)與資料訪問層(DAL),因為業務邏輯一般是固定的,所以這一方面表現不明顯。比如,第一次開發的使用者(UI)層是C/S模式,如果抽象與封裝做得好的話,那麼幾乎可以不修改程式碼,而直接用到B/S的專案上,即用網頁的表示層替換窗體(from)的表示層;還有,如果原來系統的資料訪問