[C++] クラス変数でアクセスできるメンバとできないメンバとは?
C++において、クラス変数(インスタンス変数)からアクセスできるメンバは、主にそのクラスの「アクセス修飾子」によって制御されます。
publicメンバはクラス外部からもアクセス可能で、privateメンバはクラス内部からのみアクセス可能です。
protectedメンバは、クラス自身および派生クラスからアクセスできます。
クラス変数を通じてアクセスできるのは、publicメンバと、クラス内部のメソッドからアクセスされるprivateおよびprotectedメンバです。
クラスメンバの種類とアクセス修飾子
クラスメンバとは?
クラスメンバは、クラス内で定義される変数や関数のことを指します。
これらは、クラスのインスタンス(オブジェクト)が持つ属性や動作を表現します。
クラスメンバは、オブジェクトの状態を管理したり、特定の機能を実装したりするために使用されます。
クラスメンバには、インスタンスメンバと静的メンバの2種類があります。
アクセス修飾子の役割
アクセス修飾子は、クラスメンバへのアクセス制御を行うためのキーワードです。
これにより、クラス外部からのアクセスを制限したり、特定のクラスや関数からのみアクセスできるようにしたりします。
C++では、主に以下の3つのアクセス修飾子が使用されます。
| 修飾子 | 説明 |
|---|---|
public | クラス外部からもアクセス可能 |
private | クラス内部からのみアクセス可能 |
protected | クラス内部および派生クラスからアクセス可能 |
public、private、protectedの違い
public: この修飾子が付けられたメンバは、クラスの外部からもアクセスできます。
一般的に、外部に公開したいメンバに使用します。
private: この修飾子が付けられたメンバは、クラスの内部からのみアクセス可能です。
外部からのアクセスを制限することで、データの隠蔽を実現します。
protected: この修飾子が付けられたメンバは、クラスの内部およびその派生クラスからアクセス可能です。
継承を利用したクラス設計において、特定のメンバを派生クラスに公開したい場合に使用します。
クラス変数とクラスメソッドの違い
- クラス変数: クラスに属する変数で、全てのインスタンスで共有されます。
static修飾子を使って定義されます。
- クラスメソッド: クラスに属する関数で、クラス変数や他のクラスメンバにアクセスするために使用されます。
クラスメソッドもstatic修飾子を使って定義されることがあります。
以下は、クラス変数とクラスメソッドの例です。
#include <iostream>
using namespace std;
class Example {
public:
static int classVariable; // クラス変数
static void classMethod() { // クラスメソッド
cout << "クラスメソッドが呼ばれました。" << endl;
}
};
int Example::classVariable = 0; // クラス変数の初期化
int main() {
Example::classMethod(); // クラスメソッドの呼び出し
return 0;
}クラスメソッドが呼ばれました。静的メンバ(static)の扱い
静的メンバは、クラスに属するメンバであり、全てのインスタンスで共有されます。
静的メンバは、クラスがインスタンス化される前にメモリに割り当てられ、クラスの全インスタンスで同じ値を持ちます。
静的メンバは、static修飾子を使って定義され、クラス名を通じてアクセスされます。
以下は、静的メンバの例です。
#include <iostream>
using namespace std;
class Counter {
public:
static int count; // 静的メンバ
Counter() {
count++; // コンストラクタでカウントを増やす
}
};
int Counter::count = 0; // 静的メンバの初期化
int main() {
Counter obj1; // インスタンス生成
Counter obj2; // インスタンス生成
cout << "現在のカウント: " << Counter::count << endl; // 静的メンバへのアクセス
return 0;
}現在のカウント: 2publicメンバへのアクセス
publicメンバの定義方法
publicメンバは、クラス内でpublicキーワードを使用して定義されます。
これにより、クラスの外部からもアクセス可能なメンバを作成できます。
以下は、publicメンバの定義方法の例です。
#include <iostream>
using namespace std;
class MyClass {
public:
int publicVariable; // publicメンバ変数
void publicMethod() { // publicメンバ関数
cout << "これはpublicメソッドです。" << endl;
}
};
int main() {
MyClass obj; // クラスのインスタンス生成
obj.publicVariable = 10; // publicメンバ変数へのアクセス
obj.publicMethod(); // publicメンバ関数の呼び出し
return 0;
}これはpublicメソッドです。クラス外部からのアクセス
publicメンバは、クラスの外部から直接アクセスすることができます。
インスタンスを通じて、publicメンバにアクセスすることが可能です。
以下は、クラス外部からのアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
int publicVariable; // publicメンバ変数
};
int main() {
MyClass obj; // クラスのインスタンス生成
obj.publicVariable = 20; // publicメンバ変数へのアクセス
cout << "publicVariableの値: " << obj.publicVariable << endl; // 値の表示
return 0;
}publicVariableの値: 20クラス内部からのアクセス
クラス内部からもpublicメンバにアクセスすることができます。
クラスのメンバ関数から、同じクラス内のpublicメンバにアクセスすることが可能です。
以下は、クラス内部からのアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
int publicVariable; // publicメンバ変数
void setVariable(int value) { // publicメンバ関数
publicVariable = value; // publicメンバ変数へのアクセス
}
void displayVariable() { // publicメンバ関数
cout << "publicVariableの値: " << publicVariable << endl; // 値の表示
}
};
int main() {
MyClass obj; // クラスのインスタンス生成
obj.setVariable(30); // publicメンバ関数の呼び出し
obj.displayVariable(); // publicメンバ関数の呼び出し
return 0;
}publicVariableの値: 30継承時のpublicメンバの扱い
継承を使用する場合、publicメンバは派生クラスからもアクセス可能です。
基底クラスのpublicメンバは、派生クラスのインスタンスを通じて直接アクセスできます。
以下は、継承時のpublicメンバの扱いの例です。
#include <iostream>
using namespace std;
class BaseClass {
public:
int publicVariable; // publicメンバ変数
};
class DerivedClass : public BaseClass { // BaseClassを継承
public:
void displayVariable() { // publicメンバ関数
cout << "publicVariableの値: " << publicVariable << endl; // 基底クラスのpublicメンバへのアクセス
}
};
int main() {
DerivedClass obj; // 派生クラスのインスタンス生成
obj.publicVariable = 40; // 基底クラスのpublicメンバへのアクセス
obj.displayVariable(); // 派生クラスのpublicメンバ関数の呼び出し
return 0;
}publicVariableの値: 40privateメンバへのアクセス
privateメンバの定義方法
privateメンバは、クラス内でprivateキーワードを使用して定義されます。
この修飾子を使用することで、クラスの外部からのアクセスを制限し、データの隠蔽を実現します。
以下は、privateメンバの定義方法の例です。
#include <iostream>
using namespace std;
class MyClass {
private:
int privateVariable; // privateメンバ変数
public:
void setVariable(int value) { // publicメンバ関数
privateVariable = value; // privateメンバ変数へのアクセス
}
void displayVariable() { // publicメンバ関数
cout << "privateVariableの値: " << privateVariable << endl; // 値の表示
}
};
int main() {
MyClass obj; // クラスのインスタンス生成
obj.setVariable(50); // publicメンバ関数の呼び出し
obj.displayVariable(); // publicメンバ関数の呼び出し
return 0;
}privateVariableの値: 50クラス外部からのアクセス制限
privateメンバは、クラスの外部から直接アクセスすることができません。
外部からprivateメンバにアクセスしようとすると、コンパイルエラーが発生します。
以下は、クラス外部からのアクセス制限の例です。
#include <iostream>
using namespace std;
class MyClass {
private:
int privateVariable; // privateメンバ変数
public:
void setVariable(int value) { // publicメンバ関数
privateVariable = value; // privateメンバ変数へのアクセス
}
};
int main() {
MyClass obj; // クラスのインスタンス生成
// obj.privateVariable = 60; // エラー: privateメンバへのアクセス
obj.setVariable(60); // publicメンバ関数の呼び出し
return 0;
}(コンパイルエラー)クラス内部からのアクセス
クラス内部からは、privateメンバにアクセスすることができます。
クラスのメンバ関数から、同じクラス内のprivateメンバにアクセスすることが可能です。
以下は、クラス内部からのアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
private:
int privateVariable; // privateメンバ変数
public:
void setVariable(int value) { // publicメンバ関数
privateVariable = value; // privateメンバ変数へのアクセス
}
void displayVariable() { // publicメンバ関数
cout << "privateVariableの値: " << privateVariable << endl; // 値の表示
}
};
int main() {
MyClass obj; // クラスのインスタンス生成
obj.setVariable(70); // publicメンバ関数の呼び出し
obj.displayVariable(); // publicメンバ関数の呼び出し
return 0;
}privateVariableの値: 70フレンド関数(friend)によるアクセス
フレンド関数を使用することで、privateメンバにアクセスすることができます。
フレンド関数は、特定のクラスのprivateメンバにアクセスする権限を持つ関数です。
以下は、フレンド関数によるアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
private:
int privateVariable; // privateメンバ変数
public:
MyClass(int value) : privateVariable(value) {} // コンストラクタ
friend void displayPrivateVariable(MyClass& obj); // フレンド関数の宣言
};
void displayPrivateVariable(MyClass& obj) { // フレンド関数
cout << "privateVariableの値: " << obj.privateVariable << endl; // privateメンバへのアクセス
}
int main() {
MyClass obj(80); // クラスのインスタンス生成
displayPrivateVariable(obj); // フレンド関数の呼び出し
return 0;
}privateVariableの値: 80継承時のprivateメンバの扱い
継承を使用する場合、privateメンバは派生クラスから直接アクセスすることができません。
基底クラスのprivateメンバは、派生クラスからは見えないため、アクセスするには基底クラスのpublicまたはprotectedメンバを介する必要があります。
以下は、継承時のprivateメンバの扱いの例です。
#include <iostream>
using namespace std;
class BaseClass {
private:
int privateVariable; // privateメンバ変数
public:
BaseClass(int value) : privateVariable(value) {} // コンストラクタ
int getPrivateVariable() { // publicメンバ関数
return privateVariable; // privateメンバへのアクセス
}
};
class DerivedClass : public BaseClass { // BaseClassを継承
public:
DerivedClass(int value) : BaseClass(value) {} // コンストラクタ
};
int main() {
DerivedClass obj(90); // 派生クラスのインスタンス生成
cout << "privateVariableの値: " << obj.getPrivateVariable() << endl; // 基底クラスのpublicメンバ関数の呼び出し
return 0;
}privateVariableの値: 90protectedメンバへのアクセス
protectedメンバの定義方法
protectedメンバは、クラス内でprotectedキーワードを使用して定義されます。
この修飾子を使用することで、クラスの外部からのアクセスを制限しつつ、派生クラスからはアクセス可能にすることができます。
以下は、protectedメンバの定義方法の例です。
#include <iostream>
using namespace std;
class MyClass {
protected:
int protectedVariable; // protectedメンバ変数
public:
MyClass(int value) : protectedVariable(value) {} // コンストラクタ
};
int main() {
MyClass obj(100); // クラスのインスタンス生成
// obj.protectedVariable = 200; // エラー: protectedメンバへのアクセス
return 0;
}(コンパイルエラー)クラス外部からのアクセス制限
protectedメンバは、クラスの外部から直接アクセスすることができません。
外部からprotectedメンバにアクセスしようとすると、コンパイルエラーが発生します。
以下は、クラス外部からのアクセス制限の例です。
#include <iostream>
using namespace std;
class MyClass {
protected:
int protectedVariable; // protectedメンバ変数
public:
MyClass(int value) : protectedVariable(value) {} // コンストラクタ
};
int main() {
MyClass obj(150); // クラスのインスタンス生成
// obj.protectedVariable = 250; // エラー: protectedメンバへのアクセス
return 0;
}(コンパイルエラー)クラス内部からのアクセス
クラス内部からは、protectedメンバにアクセスすることができます。
クラスのメンバ関数から、同じクラス内のprotectedメンバにアクセスすることが可能です。
以下は、クラス内部からのアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
protected:
int protectedVariable; // protectedメンバ変数
public:
MyClass(int value) : protectedVariable(value) {} // コンストラクタ
void displayVariable() { // publicメンバ関数
cout << "protectedVariableの値: " << protectedVariable << endl; // 値の表示
}
};
int main() {
MyClass obj(200); // クラスのインスタンス生成
obj.displayVariable(); // publicメンバ関数の呼び出し
return 0;
}protectedVariableの値: 200継承時のprotectedメンバの扱い
継承を使用する場合、protectedメンバは派生クラスからアクセス可能です。
基底クラスのprotectedメンバは、派生クラスのインスタンスを通じて直接アクセスできます。
以下は、継承時のprotectedメンバの扱いの例です。
#include <iostream>
using namespace std;
class BaseClass {
protected:
int protectedVariable; // protectedメンバ変数
public:
BaseClass(int value) : protectedVariable(value) {} // コンストラクタ
};
class DerivedClass : public BaseClass { // BaseClassを継承
public:
DerivedClass(int value) : BaseClass(value) {} // コンストラクタ
void displayVariable() { // publicメンバ関数
cout << "protectedVariableの値: " << protectedVariable << endl; // 基底クラスのprotectedメンバへのアクセス
}
};
int main() {
DerivedClass obj(300); // 派生クラスのインスタンス生成
obj.displayVariable(); // 派生クラスのpublicメンバ関数の呼び出し
return 0;
}protectedVariableの値: 300protectedとprivateの違い
- アクセス範囲:
privateメンバは、クラス内部からのみアクセス可能で、派生クラスからはアクセスできません。
一方、protectedメンバは、クラス内部および派生クラスからアクセス可能です。
- データの隠蔽:
privateメンバは、外部からのアクセスを完全に制限するため、データの隠蔽が強化されます。
protectedメンバは、派生クラスからのアクセスを許可するため、データの隠蔽がやや緩やかです。
以下は、protectedとprivateの違いをまとめた表です。
| 特徴 | privateメンバ | protectedメンバ |
|---|---|---|
| アクセス範囲 | クラス内部のみ | クラス内部および派生クラスから |
| 外部からのアクセス | 不可 | 不可 |
| 継承時のアクセス | 不可 | 可能 |
静的メンバ(static)のアクセス
静的メンバ変数の定義方法
静的メンバ変数は、クラス内でstaticキーワードを使用して定義されます。
静的メンバ変数は、クラスの全インスタンスで共有され、クラスがインスタンス化される前にメモリに割り当てられます。
以下は、静的メンバ変数の定義方法の例です。
#include <iostream>
using namespace std;
class MyClass {
public:
static int staticVariable; // 静的メンバ変数の宣言
static void displayVariable() { // 静的メンバ関数
cout << "staticVariableの値: " << staticVariable << endl; // 静的メンバ変数へのアクセス
}
};
int MyClass::staticVariable = 0; // 静的メンバ変数の初期化
int main() {
MyClass::staticVariable = 10; // クラス名を通じて静的メンバ変数にアクセス
MyClass::displayVariable(); // 静的メンバ関数の呼び出し
return 0;
}staticVariableの値: 10静的メンバ関数の定義方法
静的メンバ関数も、クラス内でstaticキーワードを使用して定義されます。
静的メンバ関数は、インスタンスに依存せず、クラス名を通じて呼び出すことができます。
以下は、静的メンバ関数の定義方法の例です。
#include <iostream>
using namespace std;
class MyClass {
public:
static int staticVariable; // 静的メンバ変数の宣言
static void setVariable(int value) { // 静的メンバ関数
staticVariable = value; // 静的メンバ変数へのアクセス
}
};
int MyClass::staticVariable = 0; // 静的メンバ変数の初期化
int main() {
MyClass::setVariable(20); // 静的メンバ関数の呼び出し
cout << "staticVariableの値: " << MyClass::staticVariable << endl; // 静的メンバ変数へのアクセス
return 0;
}staticVariableの値: 20クラス変数を通じた静的メンバへのアクセス
静的メンバ変数は、クラスのインスタンスを通じてアクセスすることもできますが、一般的にはクラス名を通じてアクセスすることが推奨されます。
以下は、クラス変数を通じた静的メンバへのアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
static int staticVariable; // 静的メンバ変数の宣言
void setVariable(int value) { // インスタンスメンバ関数
staticVariable = value; // 静的メンバ変数へのアクセス
}
};
int MyClass::staticVariable = 0; // 静的メンバ変数の初期化
int main() {
MyClass obj; // クラスのインスタンス生成
obj.setVariable(30); // インスタンスメンバ関数の呼び出し
cout << "staticVariableの値: " << MyClass::staticVariable << endl; // 静的メンバ変数へのアクセス
return 0;
}staticVariableの値: 30クラス名を通じた静的メンバへのアクセス
静的メンバは、クラス名を通じて直接アクセスすることができます。
これは、静的メンバがクラスに属しているためです。
以下は、クラス名を通じた静的メンバへのアクセスの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
static int staticVariable; // 静的メンバ変数の宣言
static void increment() { // 静的メンバ関数
staticVariable++; // 静的メンバ変数へのアクセス
}
};
int MyClass::staticVariable = 0; // 静的メンバ変数の初期化
int main() {
MyClass::increment(); // 静的メンバ関数の呼び出し
cout << "staticVariableの値: " << MyClass::staticVariable << endl; // 静的メンバ変数へのアクセス
return 0;
}staticVariableの値: 1静的メンバの初期化とスコープ
静的メンバ変数は、クラス内で宣言されるだけでは初期化されません。
クラス外で初期化を行う必要があります。
静的メンバ変数の初期化は、通常、クラス名を使って行います。
また、静的メンバは、プログラム全体で共有されるため、スコープはクラスに限定されません。
以下は、静的メンバの初期化とスコープの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
static int staticVariable; // 静的メンバ変数の宣言
static void reset() { // 静的メンバ関数
staticVariable = 0; // 静的メンバ変数へのアクセス
}
};
int MyClass::staticVariable = 5; // 静的メンバ変数の初期化
int main() {
cout << "初期値: " << MyClass::staticVariable << endl; // 静的メンバ変数へのアクセス
MyClass::reset(); // 静的メンバ関数の呼び出し
cout << "リセット後の値: " << MyClass::staticVariable << endl; // 静的メンバ変数へのアクセス
return 0;
}初期値: 5
リセット後の値: 0コンストラクタとデストラクタのアクセス
コンストラクタのアクセス修飾子
コンストラクタは、クラスのインスタンスが生成される際に呼び出される特別なメンバ関数です。
コンストラクタには、public、private、protectedのアクセス修飾子を指定することができます。
publicコンストラクタは、クラスの外部からインスタンスを生成するために使用され、privateやprotectedコンストラクタは、特定の条件下でのみインスタンスを生成できるように制限します。
以下は、publicコンストラクタの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { // publicコンストラクタ
cout << "インスタンスが生成されました。" << endl;
}
};
int main() {
MyClass obj; // インスタンス生成
return 0;
}インスタンスが生成されました。デストラクタのアクセス修飾子
デストラクタは、クラスのインスタンスが破棄される際に呼び出される特別なメンバ関数です。
デストラクタもコンストラクタと同様に、public、private、protectedのアクセス修飾子を指定できます。
publicデストラクタは、インスタンスが外部から破棄される際に使用され、privateデストラクタは、特定の条件下でのみインスタンスを破棄できるように制限します。
以下は、publicデストラクタの例です。
#include <iostream>
using namespace std;
class MyClass {
public:
~MyClass() { // publicデストラクタ
cout << "インスタンスが破棄されました。" << endl;
}
};
int main() {
MyClass obj; // インスタンス生成
return 0; // インスタンスが破棄される
}インスタンスが破棄されました。privateコンストラクタの使い方
privateコンストラクタは、クラスの外部からインスタンスを生成できないようにするために使用されます。
これにより、クラスのインスタンス生成を制御することができます。
以下は、privateコンストラクタの例です。
#include <iostream>
using namespace std;
class MyClass {
private:
MyClass() { // privateコンストラクタ
cout << "インスタンスが生成されました。" << endl;
}
public:
static MyClass createInstance() { // インスタンス生成を制御する静的メンバ関数
return MyClass(); // privateコンストラクタを呼び出す
}
};
int main() {
MyClass obj = MyClass::createInstance(); // 静的メンバ関数を通じてインスタンス生成
return 0;
}インスタンスが生成されました。シングルトンパターンにおけるprivateコンストラクタ
シングルトンパターンは、クラスのインスタンスが1つだけであることを保証するデザインパターンです。
このパターンでは、privateコンストラクタを使用して、外部からのインスタンス生成を防ぎます。
以下は、シングルトンパターンの実装例です。
#include <iostream>
using namespace std;
class Singleton {
private:
static Singleton* instance; // インスタンスを保持するポインタ
Singleton() { // privateコンストラクタ
cout << "シングルトンインスタンスが生成されました。" << endl;
}
public:
static Singleton* getInstance() { // インスタンスを取得する静的メンバ関数
if (instance == nullptr) {
instance = new Singleton(); // インスタンスが存在しない場合に生成
}
return instance; // インスタンスを返す
}
};
Singleton* Singleton::instance = nullptr; // インスタンスの初期化
int main() {
Singleton* obj1 = Singleton::getInstance(); // シングルトンインスタンスの取得
Singleton* obj2 = Singleton::getInstance(); // 同じインスタンスを取得
return 0;
}シングルトンインスタンスが生成されました。この例では、getInstanceメソッドを通じてのみインスタンスを取得でき、privateコンストラクタにより外部からのインスタンス生成が防がれています。
応用例:アクセス修飾子を活用した設計
カプセル化の実現
カプセル化は、オブジェクト指向プログラミングの基本的な概念であり、データとその操作を一つの単位としてまとめることを指します。
アクセス修飾子を使用することで、クラスの内部状態を隠蔽し、外部からの不正なアクセスを防ぐことができます。
以下は、カプセル化の実現例です。
#include <iostream>
using namespace std;
class BankAccount {
private:
double balance; // 残高を保持するprivateメンバ変数
public:
BankAccount(double initialBalance) : balance(initialBalance) {} // コンストラクタ
void deposit(double amount) { // 入金メソッド
if (amount > 0) {
balance += amount; // 残高を増加
}
}
void withdraw(double amount) { // 出金メソッド
if (amount > 0 && amount <= balance) {
balance -= amount; // 残高を減少
}
}
double getBalance() const { // 残高取得メソッド
return balance; // 残高を返す
}
};
int main() {
BankAccount account(1000.0); // 銀行口座のインスタンス生成
account.deposit(500.0); // 入金
account.withdraw(200.0); // 出金
cout << "残高: " << account.getBalance() << endl; // 残高の表示
return 0;
}残高: 1300継承とアクセス修飾子の組み合わせ
継承を使用することで、基底クラスの機能を派生クラスに引き継ぐことができます。
アクセス修飾子を適切に使用することで、基底クラスのメンバへのアクセスを制御し、派生クラスでの利用を制限することができます。
以下は、継承とアクセス修飾子の組み合わせの例です。
#include <iostream>
using namespace std;
class BaseClass {
protected:
int protectedVariable; // protectedメンバ変数
public:
BaseClass(int value) : protectedVariable(value) {} // コンストラクタ
};
class DerivedClass : public BaseClass { // BaseClassを継承
public:
DerivedClass(int value) : BaseClass(value) {} // コンストラクタ
void displayVariable() { // publicメンバ関数
cout << "protectedVariableの値: " << protectedVariable << endl; // 基底クラスのprotectedメンバへのアクセス
}
};
int main() {
DerivedClass obj(500); // 派生クラスのインスタンス生成
obj.displayVariable(); // 派生クラスのpublicメンバ関数の呼び出し
return 0;
}protectedVariableの値: 500フレンド関数を使った特定のアクセス許可
フレンド関数を使用することで、特定の関数に対してクラスのprivateメンバやprotectedメンバへのアクセスを許可することができます。
これにより、特定の関数がクラスの内部状態にアクセスできるようになります。
以下は、フレンド関数を使った特定のアクセス許可の例です。
#include <iostream>
using namespace std;
class MyClass {
private:
int privateVariable; // privateメンバ変数
public:
MyClass(int value) : privateVariable(value) {} // コンストラクタ
friend void displayPrivateVariable(MyClass& obj); // フレンド関数の宣言
};
void displayPrivateVariable(MyClass& obj) { // フレンド関数
cout << "privateVariableの値: " << obj.privateVariable << endl; // privateメンバへのアクセス
}
int main() {
MyClass obj(100); // クラスのインスタンス生成
displayPrivateVariable(obj); // フレンド関数の呼び出し
return 0;
}privateVariableの値: 100インターフェースクラスとアクセス修飾子
インターフェースクラスは、純粋仮想関数を持つクラスであり、他のクラスがそのインターフェースを実装することを強制します。
インターフェースクラスのメンバ関数は通常publicとして定義され、実装クラスでのアクセスを許可します。
以下は、インターフェースクラスとアクセス修飾子の例です。
#include <iostream>
using namespace std;
class IShape { // インターフェースクラス
public:
virtual void draw() = 0; // 純粋仮想関数
};
class Circle : public IShape { // IShapeを実装
public:
void draw() override { // drawメソッドの実装
cout << "円を描画しました。" << endl;
}
};
int main() {
Circle circle; // Circleのインスタンス生成
circle.draw(); // drawメソッドの呼び出し
return 0;
}円を描画しました。シングルトンパターンの実装
シングルトンパターンは、クラスのインスタンスが1つだけであることを保証するデザインパターンです。
このパターンでは、privateコンストラクタを使用して、外部からのインスタンス生成を防ぎます。
以下は、シングルトンパターンの実装例です。
#include <iostream>
using namespace std;
class Singleton {
private:
static Singleton* instance; // インスタンスを保持するポインタ
Singleton() { // privateコンストラクタ
cout << "シングルトンインスタンスが生成されました。" << endl;
}
public:
static Singleton* getInstance() { // インスタンスを取得する静的メンバ関数
if (instance == nullptr) {
instance = new Singleton(); // インスタンスが存在しない場合に生成
}
return instance; // インスタンスを返す
}
};
Singleton* Singleton::instance = nullptr; // インスタンスの初期化
int main() {
Singleton* obj1 = Singleton::getInstance(); // シングルトンインスタンスの取得
Singleton* obj2 = Singleton::getInstance(); // 同じインスタンスを取得
return 0;
}シングルトンインスタンスが生成されました。この例では、getInstanceメソッドを通じてのみインスタンスを取得でき、privateコンストラクタにより外部からのインスタンス生成が防がれています。
まとめ
この記事では、C++におけるクラスメンバのアクセス修飾子について詳しく解説し、public、private、protectedの違いや、それぞれのメンバへのアクセス方法、静的メンバの扱い、コンストラクタやデストラクタのアクセス修飾子の役割について触れました。
これらの知識を活用することで、より安全で拡張性のあるプログラム設計が可能になります。
今後は、実際のプロジェクトにおいてこれらの概念を適用し、効果的なクラス設計を行ってみてください。