第 8 章: C++ のクラスとオブジェクトの概要
オブジェクト指向プログラミング (OOP) では、クラスとオブジェクトが中心的な概念です。C++ はオブジェクト指向プログラミングをサポートする言語です。以下では、C++ のクラスとオブジェクトの概念を詳しく紹介し、豊富なコード例と実際の事例を通じて理解を深めます。
クラスとオブジェクトの基本概念
クラス
C++ では、クラスは、データとそのデータに対する操作をカプセル化することによって、同様の特性と動作を持つオブジェクトのグループを記述するユーザー定義のデータ型です。クラスは、オブジェクトのプロパティ (メンバー変数) と動作 (メンバー関数) を定義するテンプレートまたは設計図と考えることができます。
単純なクラスの例を次に示します。
#include <iostream>
using namespace std;
// 定义一个点类
class Point {
public:
// 成员变量
int x;
int y;
// 成员函数
void display() {
cout << "x = " << x << ", y = " << y << endl;
}
};
int main() {
// 创建一个Point对象
Point p1;
p1.x = 10;
p1.y = 20;
p1.display();
return 0;
}
操作結果:
x = 10, y = 20
上記のコードでは、Point
2 つのメンバー変数x
とy
1 つのメンバー関数 を含むクラスを定義しましたdisplay()
。main()
関数では、Point
クラスのオブジェクトを作成しp1
、オブジェクトを通じてそのメンバー変数にアクセスして変更し、メンバー関数を呼び出します。
物体
オブジェクトはクラスのインスタンス化、つまりクラスの定義から作成された具体的なエンティティです。各オブジェクトには、そのクラスの特定のインスタンスを表す独自のプロパティ値のセットがあります。
上記の点クラスを例にとると、複数の点オブジェクトを作成でき、各オブジェクトは異なる座標点を表します。
#include <iostream>
using namespace std;
class Point {
public:
int x;
int y;
void display() {
cout << "x = " << x << ", y = " << y << endl;
}
};
int main() {
Point p1;
p1.x = 10;
p1.y = 20;
p1.display();
Point p2;
p2.x = 30;
p2.y = 40;
p2.display();
return 0;
}
操作結果:
x = 10, y = 20
x = 30, y = 40
Point
上記のコードでは、 2 つのクラスのオブジェクトを作成しp1
、p2
それぞれ異なる座標点を表します。各オブジェクトには独自の独立した値x
とy
プロパティ値があります。
コンストラクターとデストラクター
コンストラクタ
コンストラクターは、オブジェクトの作成時に初期化に使用される特別なメンバー関数です。これはクラスと同じ名前を持ち、戻り値の型がなく、オブジェクトの作成時にのみ自動的に呼び出すことができます。
以下は、コンストラクターを定義して使用する方法を示す例です。
#include <iostream>
using namespace std;
class Point {
public:
int x;
int y;
// 默认构造函数
Point() {
cout << "调用默认构造函数" << endl;
x = 0;
y = 0;
}
// 带参数的构造函数
Point(int a, int b) {
cout << "调用带参数的构造函数" << endl;
x = a;
y = b;
}
void display() {
cout << "x = " << x << ", y = " << y << endl;
}
};
int main() {
Point p1;
p1.display();
Point p2(10, 20);
p2.display();
return 0;
}
操作結果:
调用默认构造函数
x = 0, y = 0
调用带参数的构造函数
x = 10, y = 20
上記のコードでは、Point
クラスに 2 つのコンストラクターを定義しました。1 つはデフォルトのコンストラクターで、もう 1 つはパラメーター付きのコンストラクターです。デフォルトのコンストラクターは、オブジェクトの作成時に自動的に呼び出され、0 に初期化するために使用されx
ますy
。パラメーターを持つコンストラクターは初期値を受け取りx
、y
オブジェクトの作成時に初期化されます。
デストラクター
デストラクターは、オブジェクトが破棄されたときにクリーンアップするために使用される特別なメンバー関数です。これはクラスと同じ名前で、先頭にチルダ ( ~
) が付き、パラメータと戻り値の型はなく、オブジェクトが削除されると自動的に呼び出されます。
デストラクターを定義して使用する方法を示す例を次に示します。
#include <iostream>
using namespace std;
class Point {
public:
int x;
int y;
Point() {
cout << "调用构造函数" << endl;
x = 0;
y = 0;
}
~Point() {
cout << "调用析构函数" << endl;
}
void display() {
cout << "x = " << x << ", y = " << y << endl;
}
};
int main() {
Point p1;
p1.display();
{
// 代码块内创建的对象会在其作用域结束后自动销毁
Point p2(10, 20);
p2.display();
}
return 0;
}
操作結果:
调用构造函数
x = 0, y = 0
调用构造函数
x = 10, y = 20
调用析构函数
上記のコードでは、Point
クラスのデストラクターを定義しました。このデストラクターは、オブジェクトが破棄されてスコープ外になると自動的に呼び出されます。p2
この例では、スコープの終了後にオブジェクトが破棄されるため、デストラクターが呼び出されます。
メンバーのアクセス制御
C++ では、クラス メンバー (変数や関数を含む) は、アクセス制御シンボルを通じてアクセス可能性を指定できます。C++ には、public
、 、private
の3 つのアクセス制御シンボルが用意されていますprotected
。
public
: パブリック メンバーはクラスの内部と外部の両方からアクセスできます。private
: プライベート メンバーにはクラス内でのみアクセスでき、外部から直接アクセスすることはできません。protected
: 保護されたメンバーはプライベート メンバーに似ていますが、派生クラスからアクセスできます。
以下に、さまざまなアクセス制御文字の使用例を示します。
#include <iostream>
using namespace std;
class Rectangle {
public:
// 公有成员函数
void setDimensions(int length, int width) {
if (length > 0 && width > 0) {
this->length = length;
this->width = width;
}
}
int getArea() {
return length * width;
}
private:
// 私有成员变量
int length;
int width;
};
int main() {
Rectangle rect;
// 访问公有成员函数
rect.setDimensions(5, 10);
// 访问公有成员函数
cout << "面积:" << rect.getArea() << endl;
// 下面这行代码会导致编译错误,因为length和width是私有成员,无法在外部访问
// rect.length = 2;
return 0;
}
操作結果:
面积:50
上記のコードでは、setDimensions()
と はgetArea()
オブジェクトを通じて呼び出すことができるパブリック メンバー関数です。およびlength
は、width
クラスの外部から直接アクセスできないプライベート メンバー変数です。
静的メンバー
C++ では、静的メンバーは、クラスのオブジェクトではなく、クラス全体に属するクラスのメンバーです。これはオブジェクトではなくクラスに関連付けられています。静的メンバーはクラスのすべてのオブジェクト間で共有され、オブジェクトを作成せずに直接アクセスできます。
次に、静的メンバーを定義して使用する方法の例を示します。
#include <iostream>
using namespace std;
class Circle {
public:
double radius; // 普通成员变量
static int count; // 静态成员变量
Circle(double r) {
radius = r;
count++;
}
void display() {
cout << "半径:" << radius << endl;
cout << "总数:" << count << endl;
}
static void showCount() {
cout << "当前圆的数量:" << count << endl;
}
};
int Circle::count = 0; // 静态成员变量需要在类外进行初始化
int main() {
Circle c1(1.5);
Circle c2(2.5);
c1.display(); // 访问普通成员变量和函数
c2.display();
Circle::showCount(); // 直接通过类名访问静态成员函数
return 0;
}
操作結果:
半径:1.5
总数:2
半径:2.5
总数:2
当前圆的数量:2
上記のコードでは、Circle
通常のメンバー変数radius
と静的メンバー変数を含むクラスを定義しますcount
。コンストラクター内で、count
オブジェクトが作成されるたびに増加する値。同時に、display()
円の半径と現在値を表示する通常のメンバー関数と、現在の円の番号を直接表示するcount
静的メンバー関数も定義します。showCount()
Circle
実行結果から、オブジェクトを 2 つしか作成していないにもかかわらず、count
の値が共有されており、showCount()
静的メンバー関数を通じて直接アクセスできることがわかります。
クラスの友達
C++ では、friend キーワードを使用して、関数またはクラスが別のクラスのフレンドであることを宣言できます。フレンド関数またはクラスは、それをフレンドとして宣言するクラスのプライベート メンバーにアクセスできます。
以下は、クラスの友達の使用方法を示す例です。
#include <iostream>
using namespace std;
class Rectangle {
private:
int length;
int width;
public:
Rectangle(int l, int w) {
length = l;
width = w;
}
// 声明友元函数
friend int getArea(Rectangle r);
};
// 定义友元函数,可以访问Rectangle类的私有成员
int getArea(Rectangle r) {
return r.length * r.width;
}
int main() {
Rectangle rect(5, 10);
cout << "面积:" << getArea(rect) << endl;
return 0;
}
操作結果:
面积:50
上記のコードでは、Rectangle
2 つのプライベート メンバー変数length
と を含むクラスを定義しましたwidth
。次に、クラスのプライベート メンバーにgetArea()
直接アクセスできるフレンド関数を宣言します。Rectangle
この関数では、オブジェクトmain()
を作成し、フレンド関数を通じてその面積を計算します。Rectangle
rect
継承する
継承はオブジェクト指向プログラミングにおける重要な概念であり、これにより、既存のクラス (基本クラス/親クラス) からプロパティと動作を継承する新しいクラス (派生クラス/子クラス) を作成できます。派生クラスは、基本クラスからパブリック、プロテクト、およびプライベートのメンバーを継承できます。
次に、継承の使用方法を示す例を示します。
#include <iostream>
using namespace std;
// 基类
class Shape {
protected:
int width;
int height;
public:
void setDimensions(int w, int h) {
width = w;
height = h;
}
};
// 派生类
class Rectangle : public Shape {
public:
int getArea() {
return width * height;
}
};
int main() {
Rectangle rect;
rect.setDimensions(5, 10);
cout << "矩形的面积:" << rect.getArea() << endl;
return 0;
}
操作結果:
矩形的面积:50
上記のコードには、基本クラスShape
と派生クラスがありますRectangle
。Rectangle
クラスは、Shape
クラス変数width
、height
メンバー変数、およびsetDimensions()
関数を継承します。main()
この関数では、Rectangle
オブジェクトを作成し、setDimensions()
基本クラスのメンバー関数を呼び出してそのサイズを設定します。次に、getArea()
派生クラスのメンバー関数を通じて長方形の面積を計算します。