C++ -struct 和 class 的區別

C++ -struct 和 class 的區別 (difference between class and struct in C++)

程式語言 C++ 裡,class 和 struct 到底有哪裡不一樣呢?

C++ 裡的 struct 和 class 都可以
1. 宣告成員變數
2. 宣告成員函式
3. 繼承、多型、建構子、interface

C++ 裡的 struct 和 class 不同的地方

structclass
預設 public 屬性預設 private 屬性
預設 public 繼承預設 private 繼承
不能用在 template可以用在 template

那什麼時候使用 struct,什麼時候使用 class 呢?

單純只有資料,不會針對內部成員做複雜處理的時候,使用 struct。其他時候都使用 class。

用在 template 是什麼意思?

在搜尋資料的過程中,會發現很多中國的文章就用這句話帶過去
「“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。」

但我實在還是搞不清楚這是什麼意思,所以測試了一下。

首先定義一個 class 和一個 struct,內容簡單就好,存取屬性那些也先不管。

//這個是 class
class Point1
{
public:
	Point1() { mx = 0; my = 0; }
	Point1(int x, int y) { mx = x; my = y; }
public:
	int mx, my;
};

//這個是 struct
struct Point2
{
public:
	Point2() { mx = 10; my = 10; }
	Point2(int x, int y) { mx = x; my = y; }
public:
	int mx, my;
};

然後是 template

所謂的 「關鍵字 struct 不用於定義模板參數」就看 Array3 的定義

const int MAX_NUM = 3;

//這個使用<typename T>
template<typename T>
class Array1
{
public:
	Array1()
	{
		for (int i = 0; i < MAX_NUM; i++)
			m_pArray[i] = new T;
	}
	~Array1()
	{
		for (int i = 0; i < MAX_NUM; i++)
		{
			delete m_pArray[i];
			m_pArray[i] = 0;
		}
	}
public:
	T* m_pArray[MAX_NUM];
};

//這個使用<class T>
template<class T>
class Array2
{
public:
	Array2()
	{
		for (int i = 0; i < MAX_NUM; i++)
			m_pArray[i] = new T;
	}
	~Array2()
	{
		for (int i = 0; i < MAX_NUM; i++)
		{
			delete m_pArray[i];
			m_pArray[i] = 0;
		}
	}
public:
	T* m_pArray[MAX_NUM];
};
//這個使用<struct T>,這裡編譯是不會過的
//所謂的 「關鍵字 struct 不用於定義模板參數」指的就是這裡
/*template<struct T>
class Array3
{
public:
	Array3()
	{
		for (int i = 0; i < MAX_NUM; i++)
			m_pArray[i] = new T;
	}
	~Array3()
	{
		for (int i = 0; i < MAX_NUM; i++)
		{
			delete m_pArray[i];
			m_pArray[i] = 0;
		}
	}
public:
	T* m_pArray[MAX_NUM];
};*/

但是,template 裡面還是可以塞 struct

int main()
{
	Array1<int> array1;
	*array1.m_pArray[0] = 3;
	cout << *array1.m_pArray[0] << endl;

	Array2<int> array2;
	*array2.m_pArray[0] = 4;
	cout << *array2.m_pArray[0] << endl;

	Array1<Point1> array3;
	cout << array3.m_pArray[0]->mx << " " << array3.m_pArray[0]->my << endl;

	//但是 template 裡面還是可以塞一個 struct
	Array1<Point2> array4;
	cout << array4.m_pArray[0]->mx << " " << array4.m_pArray[0]->my << endl;

	system("pause");
	return 0;
}

所以
「“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。」
(class 這個關鍵字還用於定義模板參數,就像 typename。但關鍵字 struct 不用於定義模板參數。)

意思就是


以下是題外話

在查資料的過程中,發現有一種叫做 expilcit inialization 的用法,很少看到有人在用,不過還是記在這裡。

#include <iostream>
using namespace std;

struct Foo 
{ 
	int i; 
	const char* p; 
	char c; 
};

class Bar 
{ 
	public: 
		int i; 
		const char* p; 
		char c; 
};

int main()
{
	Foo foo = {0, "hello world", '!'};
	Bar bar = {0, "hello world", '!'};
	system("pause");
	return 0;
}

若要 class 或 struct 能做這種 expilcit inialization
那它不能有 constructor,
不能有 private or protected data member,
不能有 base calss
不能有 virtual function
(C++ standard $8.5.1)。

參考資料
https://www.ptt.cc/bbs/C_and_CPP/M.1342977951.A.A2A.html
https://www.ptt.cc/man/C_and_CPP/DB9B/DE3A/M.1138892547.A.D50.htm
https://liam.page/2018/03/16/keywords-typename-and-class-in-Cxx/
https://zh.wikipedia.org/wiki/Typename
http://screamlab-ncku-2008.blogspot.com/2009/10/c-struct-class-keywords.html
https://www.justsoftwaresolutions.co.uk/cplusplus/struct_and_class.html

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *