目錄😋
任務描述
相關知識
一、不同訪問屬性成員的訪問方式
?1. public成員
?2. private成員
?3. protected成員
二、觀察構造函數和析構函數的執行過程
1. 構造函數
2. 析構函數
三、學習類的組合使用方法
1. 類的組合概念
2. 實現示例
實驗步驟
測試說明
通關代碼
測試結果
任務描述
本關任務:聲明一個簡單的Computer類,含有數據成員芯片(cpu)、內存(ram)、光驅(cdrom)等等,以及兩個公有成員函數run、stop。
相關知識
為了完成本關任務,你需要掌握
- 不同訪問屬性的成員的訪問方式
- 構造函數和析構函數的執行過程
- 類的組合使用方法
一、不同訪問屬性成員的訪問方式
訪問控制符:在 C++ 中,類的成員(包括數據成員和成員函數)可以有三種訪問控制符:
public
(公共的)、private
(私有的)和protected
(受保護的)。
?1.public
成員:可以在類的外部直接訪問。例如:
class MyClass { public:int publicVariable;void publicFunction() {// 函數體} }; int main() {MyClass obj;obj.publicVariable = 10; // 直接訪問public數據成員obj.publicFunction(); // 直接調用public成員函數return 0; }
?2.private
成員:只能在類的內部訪問。這是一種數據隱藏的機制,用于保護類的數據不被外部隨意修改。例如:
class MyClass { private:int privateVariable; public:void setPrivateVariable(int value) {privateVariable = value; // 在類內部訪問private數據成員}int getPrivateVariable() {return privateVariable; // 在類內部訪問private數據成員} }; int main() {MyClass obj;// obj.privateVariable = 20; // 錯誤,不能在類外部直接訪問private成員obj.setPrivateVariable(20); // 通過public成員函數來間接訪問和修改private成員int value = obj.getPrivateVariable();return 0; }
?3.protected
成員:它類似于
private
成員,在類的外部不能直接訪問。但是,protected
成員可以在派生類(繼承該類的子類)中訪問。例如:class BaseClass { protected:int protectedVariable; public:void setProtectedVariable(int value) {protectedVariable = value;} }; class DerivedClass : public BaseClass { public:void modifyProtectedVariable() {protectedVariable += 10; // 在派生類中訪問基類的protected成員} }; int main() {DerivedClass obj;// obj.protectedVariable = 30; // 錯誤,不能在類外部直接訪問protected成員obj.setProtectedVariable(30);obj.modifyProtectedVariable();return 0; }
二、觀察構造函數和析構函數的執行過程
1. 構造函數
- 定義和作用:構造函數是一種特殊的成員函數,它的名字與類名相同,沒有返回值類型(包括
void
)。它主要用于初始化類的對象。例如:class MyClass { public:int value;MyClass() {value = 0; // 初始化數據成員} };
- 執行時機:當創建一個對象時,構造函數會自動被調用。例如:
int main() {MyClass obj; // 調用MyClass的默認構造函數return 0; }
- 重載構造函數:可以有多個構造函數,它們的參數列表不同,這稱為構造函數的重載。例如:
class MyClass { public:int value;MyClass() {value = 0;}MyClass(int initValue) {value = initValue;} }; int main() {MyClass obj1; // 調用默認構造函數MyClass obj2(10); // 調用帶參數的構造函數return 0; }
2. 析構函數
- 定義和作用:析構函數也是一種特殊的成員函數,它的名字是在類名前面加上
~
符號,沒有參數和返回值類型。它主要用于在對象銷毀時釋放資源,如動態分配的內存、打開的文件等。例如:class MyClass { public:int* dynamicArray;MyClass() {dynamicArray = new int[10];}~MyClass() {delete[] dynamicArray; // 釋放動態分配的內存} };
- 執行時機:析構函數在對象的生命周期結束時自動被調用。如果對象是在棧上創建的,那么當對象所在的作用域結束時,析構函數就會被調用;如果對象是在堆上創建的(使用
new
創建),那么當使用delete
刪除對象時,析構函數會被調用。例如:int main() {MyClass obj1; // 在棧上創建對象,作用域結束時析構函數被調用MyClass* obj2 = new MyClass;// 使用obj2delete obj2; // 使用delete時析構函數被調用return 0; }
三、學習類的組合使用方法
1. 類的組合概念
- 類的組合是指一個類的對象作為另一個類的數據成員。通過這種方式,可以將復雜的問題分解為多個簡單的類來實現,從而提高代碼的可維護性和復用性。例如,假設有一個
Engine
類表示汽車發動機,和一個Car
類,Car
類中包含一個Engine
對象作為其數據成員來表示汽車有一個發動機。2. 實現示例
- 首先定義
Engine
類:class Engine { public:void start() {// 啟動發動機的代碼std::cout << "Engine started." << std::endl;}void stop() {// 停止發動機的代碼std::cout << "Engine stopped." << std::endl;} };
- 然后定義
Car
類,其中包含Engine
對象:class Car { private:Engine engine; public:void drive() {engine.start();// 汽車行駛的代碼std::cout << "Car is driving." << std::endl;}void park() {// 汽車停車的代碼engine.stop();} };
- 在
main
函數中使用:int main() {Car myCar;myCar.drive();myCar.park();return 0; }
- 在這個例子中,
Car
類組合了Engine
類,Car
類的對象myCar
可以通過其內部的Engine
對象engine
來調用Engine
類的成員函數start
和stop
,從而實現汽車的行駛和停車功能。
實驗步驟
參考實驗指導書第四章的實驗步驟 4:
- 聲明CPU類(可使用第二題中的CPU類)、RAM類、CDROM類。
- 聲明Computer類:聲明私有數據成員cpu、ram、cdrom,聲明公有成員函數run、stop,可在其中輸出提示信息。
- 在主程序中聲明一個Computer的對象,調用其成員函數,觀察類對象及其成員變量的構造與析構順序,以及成員函數的調用。
測試說明
根據提示,在右側編輯器補充代碼,平臺會對你編寫的代碼進行測試。
預期輸出:
構造了一個Computer! Computer開始運行! CPU開始運行! RAM開始運行! CDROM開始運行! Computer停止運行! CPU停止運行! RAM停止運行! CDROM停止運行! 析構了一個Computer!
通關代碼
#include <iostream>
using namespace std;class CPU
{
public:CPU (){}~CPU () {}void Run() {cout << "CPU開始運行!" << endl; }void Stop() {cout << "CPU停止運行!" << endl; }
};class RAM
{
public:RAM () {}~RAM () {}void Run() {cout << "RAM開始運行!" << endl; }void Stop() {cout << "RAM停止運行!" << endl; }
};class CDROM
{
public:CDROM () {}~CDROM () {}void Run() {cout << "CDROM開始運行!" << endl; }void Stop() {cout << "CDROM停止運行!" << endl; }
};class Computer
{
private:CPU cpu;RAM ram;CDROM cdrom;
public:Computer (CPU c, RAM r, CDROM cd){cpu = c;ram = r;cdrom = cd;cout << "構造了一個Computer!" << endl;}~Computer () {cout << "析構了一個Computer!"; }CPU GetCPU() const { return cpu; }RAM GetRAM() const { return ram; }CDROM GetCDROM() const {return cdrom; }void setCPU(CPU c) { cpu = c; }void setRAM(RAM r) { ram = r; }void setCDROM(CDROM cd) { cdrom = cd; }void Run() {cout << "Computer開始運行!" << endl;/********** Begin **********/cpu.Run();ram.Run();cdrom.Run();/********** End **********/}void Stop () {cout << "Computer停止運行!" << endl;/********** Begin **********/cpu.Stop();ram.Stop();cdrom.Stop();/********** End **********/}
};int main() {CPU c;RAM r;CDROM cd;Computer computer(c, r, cd);computer.Run();computer.Stop();
}