C++ 笔记(16)— 类和对象(类定义、类实例对象定义、访问类成员、类成员函数、类 public/private/protected 成员、类对象引用和指针)
1. 類的定義
類定義是以關鍵字 class 開頭,后跟類的名稱。并在它后面依次包含類名,一組放在 {} 內的成員屬性和成員函數,以及結尾的分號。
類聲明將類本身及其屬性告訴編譯器。類聲明本身并不能改變程序的行為,它定義了類的對象包括了什么,以及可以在這個對象上執行哪些操作。
例如,我們使用關鍵字 class 定義 Box 數據類型,如下所示:
class Box
{// 成員屬性double length; // 盒子的長度double breadth; // 盒子的寬度double height; // 盒子的高度// 成員函數double getVolume(void); // 返回體積
};
有時候也會把類成員的函數叫做“方法”。
2. 類實例對象的定義
類相當于藍圖,僅聲明類并不會對程序的執行產生影響。在程序執行階段,對象是類的化身。要使用類的功能,通常需要創建其實例——對象,并通過對象訪問成員方法和屬性。
聲明類的對象,就像聲明基本類型的變量一樣。
double pi= 3.1415;
Box Box1; // 聲明 Box1,類型為 Box
Box Box2; // 聲明 Box2,類型為 Box
對象 Box1 和 Box2 都有它們各自的數據成員。
就像可以為其他類型(如 int )動態分配內存一樣,也可使用 new 為 Box 對象動態地分配內存:
int* a = new int;
delete a;
Box* box = new Box();
delete box;
3. 訪問類成員
類的對象的公共數據成員可以使用直接成員訪問運算符 . 來訪問。示例:
#include <iostream>
using namespace std;class Box
{public:double length;double width;double height;
};int main()
{Box box1; // box1,類型為 BoxBox box2;double volume = 0.0;box1.length = 1;box1.width = 2;box1.height = 3;box2.length = 4;box2.width = 5;box2.height = 6;volume = box1.length * box1.width * box1.height;cout << "box1 vloume is " << volume << endl;volume = box2.length * box2.width * box2.height;cout << "box2 vloume is " << volume << endl;return 0;
}
如果有一個指針 box,它指向 Box 類的一個實例,則可使用指針運算符 -> 來訪問成員,也可使用間接運算符 * 來獲取對象,再使用句點運算符來訪問成員:
Box* box = new Box();
(*box).getVolume();
4. 類成員函數
類的成員函數是指那些把定義和原型寫在類定義內部的函數,就像類定義中的其他變量一樣。類成員函數是類的一個成員,它可以操作類的任意對象,可以訪問對象中的所有成員。
成員函數可以定義在類定義內部,或者單獨使用范圍解析運算符 :: 來定義。在類內部定義中定義的成員函數把函數聲明為內聯的(關于內聯,請參考https://www.runoob.com/w3cnote/cpp-inline-usage.html),即便沒有使用 inline 標識符。
將成員函數的定義放在類定義內有兩個作用:
- 函數將成為內聯的
inline,即編譯器為此函數的調用生成代碼時,不會生成真正的函數調用,而是將其代碼嵌入到調用者的代碼中 。 對于較小的函數,這種編譯方式會帶來很大的性能提升 ; - 每當我們對內聯函數體做出修改時, 所有使用這個類的程序都不得不重新編譯;
- 如果函數體位于類聲明之外,就不必這樣 ,只在類接口改變時才需要重新編譯用戶程序,對于大程序來說,函數體改變時無須重新編譯程序會是一個巨大的優勢 。
- 類定義變大了 。 因此 ,在成員函數定義中找到成員會變得困難 。
顯然,我們應遵循如下基本原則: 除非你明確需要從小函數的內聯中獲得性能提升,否
則不要將成員函數體放在類聲明中 。
所以您可以按照如下方式定義 getVolume 函數:
class Box
{public:double length; // 長度double breadth; // 寬度double height; // 高度double getVolume(void){return length * breadth * height;}
};
也可以在類的外部使用范圍解析運算符 :: 定義該函數,如下所示:
double Box::getVolume(void)
{return length * breadth * height;
}
在這里,需要強調一點,在 :: 運算符之前必須使用類名。調用成員函數是在對象上使用點運算符 . ,這樣它就能操作與該對象相關的數據,如下所示:
Box myBox; // 創建一個對象myBox.getVolume(); // 調用該對象的成員函數
使用上面提到的概念來設置和獲取類中不同的成員的值:
#include <iostream>
using namespace std;class Box
{public:double length;double width;double height;// 類成員函數聲明double getVolume(void);void setLength(double len);void setWidth(double wid);void setHeight(double hei);
};double Box::getVolume()
{return length * width * height;
}void Box::setHeight(double hei)
{height = hei;}void Box::setLength(double len)
{length = len;
}void Box::setWidth(double wid)
{width = wid;
}int main()
{Box box1; // box1,類型為 BoxBox box2;double volume = 0.0;box1.setLength(1);box1.setWidth(2);box1.setHeight(3);box2.setLength(4);box2.setWidth(5);box2.setHeight(6);volume = box1.getVolume();cout << "box1 vloume is " << volume << endl;volume = box2.getVolume();cout << "box2 vloume is " << volume << endl;return 0;
}
5. 類訪問修飾符
數據封裝是面向對象編程的一個重要特點,它防止函數直接訪問類類型的內部成員。類成員的訪問限制是通過在類主體內部對各個區域標記 public 、 private 、 protected 來指定的。關鍵字 public 、 private 、 protected 稱為訪問修飾符。
class Base {public:// 公有成員protected:// 受保護成員private:// 私有成員
};
一個類可以有多個 public 、 protected 或 private 標記區域。每個標記區域在下一個標記區域開始之前或者在遇到類主體結束右括號之前都是有效的。
成員和類的默認訪問修飾符是 private 。也就是說如下代碼
class X
{int func(int);
};
等價于
class X
{private:int func(int);
};
5.1 公有(public)成員
公有成員在程序中類的外部是可訪問的。可以不使用任何成員函數來設置和獲取公有變量的值,如下所示:
#include <iostream>
using namespace std;class Line
{public:double length;void setLength(double len);double getLength(void);
};// 成員函數定義
double Line::getLength(void)
{return length;
}void Line::setLength(double len)
{length = len;
}// 程序的主函數
int main( )
{Line line;// 設置長度line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl;// 不使用成員函數設置長度line.length = 10.0; // OK: 因為 length 是公有的cout << "Length of line : " << line.length <<endl;return 0;
}
5.2 私有(private)成員
私有成員變量或函數在類的外部是不可訪問的,甚至是不可查看的。只有類和友元函數可以訪問私有成員。
默認情況下,類的所有成員都是私有的。例如在下面的類中, width 是一個私有成員,這意味著,如果您沒有使用任何訪問修飾符,類的成員將被假定為私有成員:
class Box
{double width;public:double length;void setWidth( double wid );double getWidth( void );
};
實際操作中,我們一般會在私有區域定義數據,在公有區域定義相關的函數,以便在類的外部也可以調用這些函數,如下所示:
#include <iostream>
using namespace std;class Box
{public:double length;void setWidth(double wid);double getWidth(void);private:double width;
};// 成員函數定義
double Box::getWidth(void)
{return width ;
}void Box::setWidth(double wid)
{width = wid;
}// 程序的主函數
int main( )
{Box box;// 不使用成員函數設置長度box.length = 10.0; // OK: 因為 length 是公有的cout << "Length of box : " << box.length <<endl;// 不使用成員函數設置寬度// box.width = 10.0; // Error: 因為 width 是私有的box.setWidth(10.0); // 使用成員函數設置寬度cout << "Width of box : " << box.getWidth() <<endl;return 0;
}
C++ 提供了一種很有用的簡化功能 ,可用來描述沒有私有實現細節的類,這種語法功能就是結構體 ( struct ),一個結構體就是一個成員默認為公有屬性的類 。
struct People
{int age;
};
等價于
class People
{public:int age;
};
結構體主要用于成員可以取任意值的數據結構 。
5.3 保護(protected)成員
保護成員變量或函數與私有成員十分相似,但有一點不同,保護成員在派生類(即子類)中是可訪問的。
從下面的實例中,我們從父類 Box 派生了一個子類 smallBox。下面的實例與前面的實例類似,在這里 width 成員可被派生類 smallBox 的任何成員函數訪問。
#include <iostream>
using namespace std;class Box
{protected:double width;
};class SmallBox:Box // SmallBox 是派生類
{public:void setSmallWidth( double wid );double getSmallWidth( void );
};// 子類的成員函數
double SmallBox::getSmallWidth(void)
{return width ;
}void SmallBox::setSmallWidth( double wid )
{width = wid;
}// 程序的主函數
int main( )
{SmallBox box;// 使用成員函數設置寬度box.setSmallWidth(5.0);cout << "Width of box : "<< box.getSmallWidth() << endl;return 0;
}
6. 類對象引用
我們說引用就像是給變量起了一個別名,對這個引用的操作就和操作這個變量本身一樣。
對象也可以有引用,聲明一個對象的引用方法是:
類名 &對象名 a=對象名 b;
此時,對對象 a 的訪問和操作就如同對對象 b 的訪問和操作一樣,對象 a 只是對象 b 的一個別名。
int main( )
{Box box; // 聲明一個 box 對象Box &b = box; // 聲明一個 box 引用b.setWidth(1.0); // 效果與 box.setWidth(1.0) 相同b.getWidth(); // 效果與 box.getWidth 相同return 0;
}
7. 類對象指針
由于類和結構的相似性,對象指針和結構指針的使用也是相似的。我們也是使用箭頭操作符 -> 來訪問該指針所指向的對象的成員數據或成員函數。
int main( )
{Box box; // 聲明一個 box 對象Box *b = &box; // 聲明一個對象指針b->setWidth(1.0); // 效果與 box.setWidth(1.0) 相同b->getWidth(); // 效果與 box.getWidth 相同return 0;
}
參考:
https://www.runoob.com/cplusplus/cpp-class-access-modifiers.html
總結
以上是生活随笔為你收集整理的C++ 笔记(16)— 类和对象(类定义、类实例对象定义、访问类成员、类成员函数、类 public/private/protected 成员、类对象引用和指针)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《琴》是哪个时期的作品?
- 下一篇: 《琴》是谁的作品?