このブログ記事では、C++におけるフレンド, Deleted, Defaulted関数を紹介します。

フレンド関数
クラスの外で定義された関数が、そのクラスのプライベートメンバーにアクセスする必要がある場合、フレンド関数を使用できます。
class Private {
friend void double_value(Private& private);
private:
int value;
void add(int x) {
value += x;
};
public:
void print() {
cout << value << endl;
};
Private(int value) : value(value) {};
};
void double_value(Private& private) {
private.add(private.value);
};
int main () {
Private private(5);
double_value(private);
private.print(); // => 10!
return 0;
}
friend
キーワードを使用して double_value
関数がフレンド関数であることを示すと、
double_value
関数はプライベート属性 private.value
とプライベートメソッド private.add
にアクセスすることが許可されます。
フレンド関数の主な用途は、左側にクラス自身が来ない場合にオペレーターをオーバーロードする場合です。 クラス内でのオペレーターオーバーロードは、クラスインスタンスが左側に来ることを前提としますが、 フレンド関数にはその前提がありません。
class Counter {
friend Counter operator+(int n, Conuter counter);
private:
int count;
public:
Counter(int count) : count(count) {};
Counter operator+(int n) {
int new_count = count + n;
// The above assumes Counter is on the left.
return Counter(new_count);
}
};
Counter operator+(int n, Counter counter) {
int new_count = n + counter.count;
return Counter(new_count);
};
int main () {
Counter c1(1);
Counter c2 = 3 + c1; // c2.count = 4
Counter c3 = c2 + 3; // c3.count = 7
return 0;
}
Deleted関数
static
キーワードを使用すると、クラス全体で使用できる静的メンバ変数(またはクラス変数)を作成できます。
これを利用して、たとえば一意のIDを生成することができます。
class User {
static int next_id;
public:
int unique_id;
User() {
unique_id = next_id;
next_id++;
}
}
int User::next_id = 1;
int main () {
User user1;
User user2;
User user3;
cout << "User1 ID: " << user1.unique_id << endl;
cout << "User2 ID: " << user2.unique_id << endl;
cout << "User3 ID: " << user3.unique_id << endl;
// => User1 ID: 1
// User2 ID: 2
// User3 ID: 3
return 0;
}
ただし、デフォルトでコピーコンストラクタや代入演算子が利用可能なため、
同じ unique_id
が異なるインスタンスに割り当てられる可能性があります。
int main () {
User user1;
User user2 = user1; // Copy Constructor
User user3;
user3 = user1; // Assignment Operator =
cout << "User1 ID: " << user1.unique_id << endl;
cout << "User2 ID: " << user2.unique_id << endl;
cout << "User3 ID: " << user3.unique_id << endl;
// => User1 ID: 1
// User2 ID: 1
// User3 ID: 1
return 0;
}
これを防ぐために、コピーコンストラクタと代入演算子を Deleted関数 として宣言し、
これらの操作が実行できないようにして unique_id
の一意性を確保します。
class User {
static int next_id;
public:
int unique_id;
User() {
unique_id = next_id;
next_id++;
}
User(User& user) = delete; // Copy Constructor Deleted
User& operator=(User& user) = delete; // Assignment Operator Deleted
}
Defaulted関数
パラメータ付きコンストラクタを定義すると、クラスのデフォルトコンストラクタは自動的に無効化されます。
class Counter {
public:
int count;
Counter (int count) : count(count) {};
};
int main () {
Counter counter; // Err!
return 0;
}
デフォルトコンストラクタを有効にするには、default
キーワードを使用します。
class Counter {
public:
int count;
Counter (int count) : count(count) {};
Counter () = default;
};
int main () {
Counter counter; // No Err
return 0;
}
リソース
- Portfolio Courses. 2022. Friend Functions | C++ Tutorial. YouTube.
- Portfolio Courses. 2022. Operator Overloading Using Friend Functions | C++ Tutorial. YouTube.
- Portfolio Courses. 2022. Deleted Functions | C++ Tutorial. YouTube.
- Portfolio Courses. 2022. Defaulted Functions | C++ Tutorial. YouTube.