c++之基於對象程序設計

一、概括:

1.1、解決複雜問題的途徑無非就是把問題分割成簡單的問題。

1.2、在面向過程的編程語言中(例如c語言),我們考慮問題的核心是過程、是算法、是解決問題的步驟,其次纔是算法過程中需要的數據。所以對於c語言來說,分割複雜問題理所當然就是對過程的分割,我們把整個程序過程分割成函數,然後可以把函數按照功能或者其他規則分別存儲在多個源文件中。

1.3、在小規模的程序設計中,面向過程的編程方法具有高效率,快速等等優點,但是隨着程序規模的不斷增大,通過簡單的對過程的分割變得困難,所以產生了基於對象和麪向對象的程序設計方法。

二、基於對象的設計方法

2.1、基於對象的設計方法把考慮問題的核心由過程轉向了數據,過程依附於數據,在c++中,用戶可以自定義類型,並且這種類型通過c++提供的各種設施可以讓編譯器同等對待。

例如我們定義了整數a,int a=2,a是編譯器內置支持的數據類型,我們可以對a進行算數,移位,關係運算等操作,當我們把一個浮點數賦值給a的時候,編譯器還會檢查類型錯誤。我們現在把a看成是具有這些操作的對象,用戶也可以定義自己的類型,編譯器也會進行類型檢查,不同的是我們自己定義的數據類型所具有的各種操作需要我們自己定義。

2.2、c++給我們提供創建自己的數據類型的能力,這樣就很容易根據問題來構建和問題相對應的數據類型,並由此產生對象,這種能力在系統資源與問題之間搭起了橋樑,使程序更容易設計、維護。

三、定義自己的數據類型(類類型)

#include <stdio.h>
#include <stdlib.h>

/*
類類型不僅可以讓我們把數據可以數據對應的操作捆綁在一起還可以提供以下機制
1、提供了一個作用域範圍
2、可以對類作用域範圍的類成員訪問進行控制
3、其他見下文
*/
class person //定義了自己的數據類型
{
public:
	void age(void)
	{
		printf("my age is %d\n",_age);
	}
private:
	int _age;
};

int main(void)
{
	person me; //用自定義的數據類型產生對象
	me.age();
	system("pause");
	return 0;
}

四、讓類類型成爲一等公民

用於自定義類型要想和內置類型具有同等的地位,必須需要做出各種處理。

4.1、類對象的初始化

在c語言中,爲初始化的全局變量是類型相對應的初始值,例如整數是0,浮點數是0.0,c++對於類對象的初始化我們可以有更多的控制,因爲類對象可以含有多個成員,所以c++利用構造函數對類對象進行初始化。

4.1.1、如果用戶沒有爲類類型提供構造函數,那麼c++將會提供一個默認的構造函數,隨着對象所處作用域的不同,類成員的初始值也不一樣。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
	void age(void)
	{
		printf("my age is %d\n",_age);
	}
private:
	int _age;
};

person me; //在全局作用域範圍的類對象成員被初始化爲0

int main(void)
{
	person you; //在棧中的類對象爲隨機值
	person *him=new person(); //在堆中的類對象成員被初始化爲0
	me.age();
	you.age();
	him->age();
	system("pause");
	return 0;
}

4.1.2、默認函數賦予的類對象成員的初始值往往不能滿足我們的需要,可以自定義構造函數,構造函數是可重載的,一旦用戶提供構造函數,c++將不再提供默認構造函數。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
	person(){_age=30;} //無參構造函數
	person(int age){_age=age;}//帶參構造函數
	void age(void)
	{
		printf("my age is %d\n",_age);
	}
private:
	int _age;
};


int main(void)
{
	person you;
	you.age();
	person me(28);
	me.age();
	system("pause");
	return 0;
}

4.1.3、無參構造函數和有參構造函數解決了我們定義類對象時的類對象的初值問題,而拷貝構造函數可以使我們使類對象像用戶對象一樣的進行賦值,當我們沒有定義類的拷貝構造函數時,相同類型對象之間的賦值會被簡單的處理成位拷貝,而我們可能只是需要另一個對象的一部分,或者是需要進行深拷貝時就需要自己定義拷貝構造函數。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
	person(int age=30){_age=age;}//帶參構造函數
	person(const person& other);//const 可選
	person(const person* other);//指針類型也可以

	void age(void)
	{
		printf("my age is %d\n",_age);
	}
private:
	int _age;
};

person::person(const person& other)
{
	_age=other._age+1; //改變默認拷貝構造函數的行爲
}

person::person(const person* other)
{
	_age=other->_age - 1;
}

int main(void)
{
	person you;
	you.age();
	person me(28);
	me.age();
	person him=you;
	him.age();//31
	person her=&you;
	her.age();
	system("pause");
	return 0;
}

4.1.4、靜態成員,const成員及其初始化

類類型的靜態成員就是類作用域內的全局變量,而const成員和引用成員由於在成員被創立時就要確定其初值,所以他們的初始化需要成員初始化列表來完成。

可以理解爲類對象的初始化分成兩個步驟,開闢空間及對空間進行賦值,const和引用成員必須在開闢空間的步驟就要初始化,放到成員初始化列表裏就可以達到這一目的。

#include <stdio.h>
#include <stdlib.h>

class person
{
public:
	person(int age=30,const char* name="justsong"):_name(name){_age=age;}//帶參構造函數,多個初始化列表用逗號分開
	person(const person& other);//const 可選
	static const char *_country;//靜態變量也要受訪問權限的限制

	void age(void){	printf("my age is %d\n",_age); }
	void country(void){ printf("%s\n",_country);}
	void name(void){ printf("%s\n",_name);}
private:
	int _age;
	const char * _name; //需要利用成員初始化列表進行初始化
};

person::person(const person& other)
{
	_age=other._age+1; //改變默認拷貝構造函數的行爲
}

const char * person::_country="china"; //靜態成員的初始化必須加上類型

int main(void)
{
	person you;
	you.age();
	you.country();
	you.name();
	system("pause");
	return 0;
}

4.1.5、至此我們的對象可以像內置類型對象一樣進行類型檢查,賦值操作,並且可以很好的進行初始化,通過操作符重載可以讓內置的操作符作用於自定義類對象。


4.1.6、類類型的其他細節





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章