コード例:
class my
{
int x;
public:
my(int a)
{
x = a;
}
my(my &obj)
{
x = obj.x;
}
.
.
}
int main(void)
{
my object1(5);
my object2(object1);
return 0;
}
object2はobject1を渡すことによってどのように初期化されますか?object1がメンバーにx
直接アクセスできないことがわかる限り、object2の初期化にどのように役立ちますか?
アクセス制御(パブリック/プライベート/保護)は、コードの一部がクラスのメンバーの名前を合法的に参照できるかどうかを制御します。ここでは、個々のオブジェクトは役割を果たしません。全体の問題は、コードと名前だけです。
質問のコンストラクター、フレンド関数、フリー関数を比較してみましょう。
class my
{
int x;
friend void fr(my&);
public:
my(my &obj)
{
x = obj.x;
}
};
void fr(my &obj)
{
obj.x += 1;
}
void nonfr(my &obj)
{
obj.x += 2;
}
ステートメントを取りx = obj.x;
ます。ステートメントはコードの一部です。そのコードはどこにありますか?クラスのコンストラクター内my
。つまり、これはクラスの一部であり、名前にアクセスできますobj.x
。
次に、ステートメントobj.x += 1;
。そのコードはどこにありますか?fr
クラスの友達である関数の内部my
。友達なので、名前にアクセスできますobj.x
。
最後に、ステートメントobj.x += 2;
。そのコードはどこにありますか?関数内nonfr
。nonfr
はクラスとは関係のない通常の関数であるため、クラスmy
のプライベート(または保護された)メンバーの名前にアクセスする権利がないmy
ため、コンパイルに失敗します。
サイドノート:
通常、コピーコンストラクターは、次のようにconstを参照してパラメーターを取得する必要があります。
my(const my &obj)
非const参照を使用するコピーコンストラクターは、ソースオブジェクトを変更する可能性があり、それらの実行可能なユースケースは非常にまれです。一時的なものからのコピーを防ぐことは言うまでもありません。なぜなら、それらは非const参照にバインドできないからです。
また、コンストラクター内での割り当てではなく、mem-initialiser-listsを使用することをお勧めします。これは、コンストラクターが最初にメンバーを初期化し、次にそれを割り当てるためです。したがって、全体として、コンストラクターは次のようになります。
my(const my &obj) : x(obj.x)
{}
コピーコンストラクターで特別な処理が必要でない限り(ここでは行いません)、それを宣言してコンパイラーに生成させるべきではないという事実は言うまでもありません。詳細については、Rule ofZeroおよびRuleofThreeを参照してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加