C++ 類 class的一系列問題
阿新 • • 發佈:2018-12-14
c++類定義
衍生於結構體Struct,
定義了類物件包括什麼(資料成員, 屬性)和可以對這個物件進行什麼操作(操作)。
類定義的一般格式:
class 類名{
//資料成員
《《private:》
成員1;》
《public:
成員2;》
《protected:
成員3;》
//函式操作
《《private:》
函式返回型別 函式名(引數){函式體};》
《public:
成員2;》
《protected:
成員3;》
}
比如下列程式碼:
class Box
{
public:
double length; // 長度
double breadth; // 寬度
double height; // 高度
double getVolume()
{
return length * breadth * height;
}
};
需要注意:
- {}之內為類體,定義資料成員和函式操作
- public, private, protected 為訪問限定符
- 這三種限定符的作用域為:從該說明符出現開始到下一個說明符之前或類體結束之前
- 如果類體開始沒有限定符修飾,預設為private
- 對於訪問,只有public修飾的,可以通過物件訪問,而private和protected不可通過類物件訪問。還有一部分是在繼承處使用
資料成員的訪問
可以通過**直接成員訪問運算子(.)**來訪問成員。
#include <iostream>
using namespace std;
class Box
{
public:
double length; // 長度
double breadth; // 寬度
double height; // 高度
double getVolume()
{
return length * breadth * height;
}
};
int main ( )
{
Box Box1; // 宣告 Box1,型別為 Box
Box Box2; // 宣告 Box2,型別為 Box
double volume = 0.0; // 用於儲存體積
// box 1 詳述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 1 的體積
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Box1 的體積:" << volume <<endl;
// box 1的體積
volume = box1.getVolume()
cout << "Box2 的體積:" << volume <<endl;
return 0;
}
物件的建立和引用
- 直接定義類的例項–物件
Box box1
Box box1(引數值)
涉及到建構函式 - 動態建立
- 建立
指標變數名 =new型別名(初始化方式)
- 刪除
delete 指標名
- 建立
Box *pbox1=new Box();
delete pnox1;
c++ 類成員函式
1. 在類體內直接定義函式
2. 在類外定義函式
要使用範圍解析運算子 ::,比如說在類內宣告,類外定義函式getVolume()
:
class Box
{
public:
double length; // 長度
double breadth; // 寬度
double height; // 高度
double getVolume();
};
double Box:: getVolume() {
return length * breadth * height;
}
注意:
- 範圍解析運算子
::
前面加類名,表明該函式屬於此類中 - 成員函式與內聯 inline
用於消除呼叫函式是所造成的固定時間的消耗的方法。
在編譯階段將使用函式的定義體來替代函式呼叫語句c++行內函數解釋
預設在類體內實現的成員函式都是內聯的;如果在類體外定義函式,而僅在類體內給出函式宣告,如果要實現內聯,則在類外函式定義前加關鍵字inline
class A
{
public:
void Foo(int x, int y);
}
inline void A::Foo(int x, int y){} ;
建構函式和解構函式
- 建構函式
-
定義:
類名(引數){}
-
類的建構函式是類的一種特殊的成員函式,它會在每次建立類的新物件時執行,並在在該物件的生命週期中只會呼叫一次
-
建構函式的名稱與類的名稱是完全相同的
-
無函式返回型別,建構函式可用於為某些成員變數設定初始值
-
建構函式可以過載,用不同的引數表區分
-
若類定義中沒有給出任何建構函式,c++編譯器會自動生成預設的建構函式:
類名 (){}
,但是,只有程式設計師定義一個建構函式,系統就不會生成預設的建構函式
//演示過載建構函式
#include <iostream>
#include<cstring>
using namespace std;
class CGoods
{
public:
CGoods();
CGoods(char [], int, float);
CGoods(char[], float);
private:
char Name[20];
int Amount;
float Price;
float Total_value;
};
// 建構函式定義
CGoods::CGoods(){
Name[0]='\0';
Price=0.0;
Amount=0;
Total_value=0.0;
}
CGoods::CGoods(char name[], int amount, float price){
strcpy(Name, name);
Price=price;
Amount=amount;
Total_value=0.0;
}
CGoods::CGoods(char name[], float price){
strcpy(Name, name);
Price=price;
Amount=0;
Total_value=0.0;
}
注意:
-
如果想使用預設的建構函式,則在定義物件時不能使用括號
比如:
CGoods Car3;
Car3為CGoods類的物件,定義時呼叫不帶引數的建構函式,
而,
CGoods Car4();
實際上並沒有呼叫預設的建構函式,而是定義一個函式宣告。 -
建構函式的另一種初始化方式:
類名(引數列表): 資料成員1(引數值1), 資料成員2(引數值2)[...]
#include <iostream>
#include <stdlib.h>
using namespace std;
class CMyClass {
public:
CMyClass(int);
int getx() { return m_x; };
int gety() { return m_y; };
private:
int m_x;
int m_y;
};
CMyClass::CMyClass(int i) : m_y(i), m_x(m_y)
{
};
/*
CMyClass::CMyClass(int i) {
m_y = i;
m_x = m_y;
};
*/
int main()
{
CMyClass a(1);
cout << a.getx() << endl << a.gety() << endl;
system("pause");
return 0;
}
out:
-858993460
1
而正常的在建構函式內部初始化,則不受影響,注意執行一下程式碼中註釋的部分
2. 解構函式
在定義一個物件時,C++會自動呼叫建構函式建立該物件並完成初始化,而當一個物件的生命週期結束時,C++編譯器會自動呼叫一個特殊的成員函式–解構函式,進行善後工作
- 解構函式的名稱與類的名稱是完全相同的,只是在前面加了個波浪號(~)作為字首
- 無函式返回型別,並且無任何引數
- 一個類中有且只能有一個解構函式,可以預設
- 在登出物件是,系統會自動呼叫解構函式,通常在解構函式中完成關閉檔案,釋放記憶體等操作
#include <iostream>
#include <stdlib.h>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 這是建構函式宣告
~Line(); // 這是解構函式宣告
private:
double length;
};
// 成員函式定義,包括建構函式
Line::Line(void)
{
cout << "Object is being created" << endl;
}
Line::~Line(void)
{
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
// 程式的主函式
int main( )
{
Line line;
// 設定長度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
system("pause");
return 0;
}