天天看點

C++中的類的const成員和static成員

const成員函數 :在成員函數後面加const,const修飾this指針所指向的對象,也就是保證調用這個const成員函數的對象在函數内不會被改變。

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	void Show1() const                                       //const Date* this
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

	void Show2()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}


	void F1()
	{
		Show1();
		Show2();
	}

	void F2()const
	{
		Show1();
		//Show2();                       //出錯,const調用非const成員函數
	}
private:
	int _year;
	int _month;
	int _day;
};
           

1. const對象可以調用非const成員函數?                                             不可以>權限放大

2. 非const對象可以調用const成員函數嗎?                                     可以>權限縮小

3. const成員函數内可以調用其它的const成員函數非const成員函數嗎?            可以, 不可以

4. 非const成員函數内可以調用其它的const成員函數非const成員函數嗎?           可以    ,可以

C++中的類的const成員和static成員

類的靜态成員:聲明為static的類成員(成員資料或成員函數)稱為類的靜态成員

特征:

1.靜态成員為所有類對象所共享,不屬于某個具體的執行個體

2.類靜态成員即可用類名::靜态成員或者對象.靜态成員來通路

3.類靜态成員變量必須在類外定義,定義時不添加static關鍵字

4.類的靜态成員函數沒有預設的this指針,是以在它裡面不能使用任何非靜态成員

5.靜态成員和類的普通成員一樣,也有public、protected、private3種通路級别,也可以具有傳回值,const修飾符等參數

#include <iostream>
using namespace std;

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{
		++_count;
	}

	Date(const Date& d)
		:_year(d._year)
		,_month(d._month)
		,_day(d._day)
	{
		++_count;
	}

	void Show() const 
	{
		cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
		GetCount();
	}

	// 沒有this指針
	static int GetCount()
	{
		//_year = 10;
		//Show();
		return _count;
	}
private:
	int _year;
	int _month;
	int _day;

	static size_t _count;
};

size_t Date::_count = 0;

int main()
{
	Date d1(2018, 3, 26);
	Date d2(2018, 3, 26);

	cout<<d1.GetCount()<<endl;
	cout<<d2.GetCount()<<endl;
	cout<<Date::GetCount()<<endl;                     //通過類名通路靜态成員函數

	return 0;
}
           

1. 靜态成員函數可以通路非靜态的成員嗎?        不能通路,靜态成員函數沒有this指針

2. 非靜态的成員函數可以通路靜态成員嗎?       可以通路,通過類域進行通路

再探拷貝構造函數的優化:

在一個步驟中,先構造了一個臨時對象,又用該臨時對象拷貝構造其他對象,會将二者合二為一

#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;
	}

};

void fun1 (const Date& d)  
{}

Date fun2()
{
	//Date ret;
	//return ret;              //這裡發生拷貝構造臨時對象,ret被析構
	return Date();             //直接傳回匿名對象,優化了拷貝構造
}

void fun3(Date d)                 //傳值,多調用一次拷貝構造,還要調析構
{

}

int main()
{
        //情景1
        //Date d1;
	//fun1(d1);	//d1已經存在,不會調用拷貝
	
	//情景2    一次構造,一次析構
	//fun3(Date());	//在一個步驟中,先構造了一個臨時對象,又用該臨時對象拷貝構造其他對象,會将二者合二為一,調用了構造,然後直接進行拷貝構造
	//fun1(Date());	//結果相同,意義不同,這裡d是Date()的别名

	Date d1 = fun2();//fun2中進行一次構造,一次拷貝構造
	
	//Date d2;		//構造
	//d2 = fun2();	//構造、拷貝構造、指派運算符重載
	
	//Date d3;	
	//Date();// 臨時對象,匿名對象,聲明周期隻在目前一行

	//Date().Show(); // 臨時對象,匿名對象,聲明周期隻在目前一行,(使用場景:隻是調用一下某個對象的某個函數,調完以後不會再
														//			用該對象,調用結束,立刻析構)


	return 0;
}



#include <iostream>

using namespace std;


class AA
{
public:
	AA()
	{
		cout << "AA()" << endl;
	}

	AA(const AA& A)
	{
		cout << "const AA(AA& A)" << endl;
	}

	AA& operator=(const AA& A)
	{
		cout << "AA& operator=(const &AA A)" << endl;
		
		return *this ;
	}

};
AA f(AA a)
{
	return a;
}
void Test1()             //二次拷貝構造,1次指派運算符的重載
{
	AA a1;
	a1 = f(a1);
}
void Test2()             //二次拷貝構造,0次指派運算符的重載
{
	AA a1;
	AA a2 = f(a1);
}

void Test3()             //三次拷貝構造,0次指派運算符的重載
{
	AA a1;
	AA a2 = f(f(a1));
}


int main()
{
	printf("test1:\n");
	Test1();
	printf("test2:\n");
	Test2();
	printf("test3:\n");
	Test3();
	return 0;
}
           
C++中的類的const成員和static成員

繼續閱讀