error: is private within this context の原因と直し方
private指定されたクラスのメンバ変数に、クラスの外から直接アクセスしようとしたときに出るエラーです。カプセル化のためにprivateメンバは外部から直接触れないようになっています。
エラーメッセージの読み方
main.cpp:8:7: error: 'int Account::balance' is private within this context
main.cpp- ファイル名
8- 行番号
7- 列番号 — この位置でg++が構文解析に失敗しました
'int Account::balance' is private within this context- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <iostream> 2 class Account { 3 private : ^ 4 int balance = 0; 5 }; 6 int main() { 7 Account a; 8 a.balance = 100; 9 std::cout << "done" << std::endl; 10 return 0; 11 }
balanceはprivateなので、クラスの外にあるmain関数から直接触ることはできません。外部から操作させたいならpublicにする必要があります。
直し方: private を public にします。
パターン2
1 #include <iostream> 2 class Robot { 3 private : ^ 4 int power = 0; 5 }; 6 int main() { 7 Robot r; 8 r.power = 50; 9 std::cout << "done" << std::endl; 10 return 0; 11 }
アクセス制御はインスタンスの有無ではなく、コードがクラスの内側かどうかで決まります。
直し方: private を public にします。
パターン3
1 #include <iostream> 2 class Wallet { 3 private : ^ 4 int coins = 0; 5 }; 6 int main() { 7 Wallet w; 8 w.coins = 20; 9 std::cout << "done" << std::endl; 10 return 0; 11 }
本来はゲッター・セッターを用意してカプセル化を保つのが望ましいですが、ここではpublicにすることでエラーの原因だけを直しています。
直し方: private を public にします。
パターン4
1 #include <iostream> 2 class Car { 3 private : ^ 4 int speed = 0; 5 }; 6 int main() { 7 Car c; 8 c.speed = 40; 9 std::cout << "done" << std::endl; 10 return 0; 11 }
speedはprivateなので、クラスの外にあるmain関数から直接触ることはできません。
直し方: private を public にします。
パターン5
1 #include <iostream> 2 class Player { 3 private : ^ 4 int hp = 0; 5 }; 6 int main() { 7 Player p; 8 p.hp = 100; 9 std::cout << "done" << std::endl; 10 return 0; 11 }
外部から操作させたいメンバはpublicにする必要があります。
直し方: private を public にします。
よくある誤解
「クラスのインスタンスを持っていればどのメンバにもアクセスできる」というのは誤解です。C++のアクセス制御はインスタンス単位ではなく、コードがそのクラスの内側にあるかどうかで決まります。外部から操作したいならpublicなメソッド(ゲッター・セッター)を用意する必要があります。
実務での勘所
カプセル化には、friendという明示的な例外を認める仕組みも用意されています。特定の関数やクラスをfriendとして宣言すると、そのクラスや関数だけはprivateメンバに直接アクセスできるようになります。ゲッター・セッターを介した緩やかな公開と違い、friendは「このクラス(または関数)だけには内部を見せてよい」と名指しで許可する、より強い結びつきを作る機能です。乱用するとカプセル化の意味が薄れるため、演算子オーバーロードなど本当に必要な場面に限定して使うのが定石です。