ためになるホームページ お問い合わせ




TOP > C++ > オブジェクトの利用の注意
オブジェクトの代入
同じ型のクラス同士は、オブジェクトの代入ができる。オブジェクトの代入を行うと、各メンバがbit単位でコピーされる。オブジェクト自体のアドレジスは作成したアドレスのままです。
ここで、問題が生じます。例えば、あるメンバ変数が動的にとるポインタであった時、そのアドレスまでもがコピーされます。すなわち、動的に2つのメンバをとっても代入する事によって、代入した方の先頭のアドレスがわからなくなります。
この時は、コピーコンストラクタを用い、別途に動的に割り当てて以前のアドレスを書き換えないようにしなければなりません。
以下にオブジェクトの代入を示しますが、実行しないで下さい。

オブジェクトの代入の例
#include <iostream>
using namespace std;

class parentC
{
  int privateA;
  int *privateB;
public:
  parentC();
  ~parentC();
  void show();
  void set(int a);
};

parentC::parentC()
: privateA(0)
{
  privateB = new int[2];
}

parentC::~parentC()
{
  delete[] privateB;
}

void parentC::show()
{
  cout << "privateA = " << privateA << endl;
  cout << "addr privateB = " <<  privateB << endl;
}

void parentC::set(int a)
{
  privateA = a;
}

int main()
{
  parentC parentA;
  cout << "parentAのprivateAに値をセットします" << endl;
  parentA.set(3);

  cout << "parentAのメンバ変数の値を表示します" << endl;
  parentA.show();
  parentC parentB = parentA;
  cout << "parentBのメンバ変数の値を表示します" << endl;
  parentB.show();
  return 0;
}


オブジェクトを関数に引数として渡す
オブジェクトを関数の引数に渡すと値渡しが行われ、bit単位で正確なコピーが作成される。よって、受け取った内部で修正を加えても元のオブジェクトのメンバは影響を受けない。
オブジェクトのポインタを引数として渡すと、関数内部で元のオブジェクトのメンバを修正することができる。
オブジェクトを引数で渡す時の注意点は、値渡しを行うとそのコピーのオブジェクトのデストラクタが関数を抜ける時に呼ばれる事である。デストラクタ内で、メモリの解放を行うなどの処理を行うとプログラムが正常に動かなくなる。

オブジェクトを関数に引数として渡す例
#include <iostream>
using namespace std;

class parentC
{
public:
  parentC();
  ~parentC();
};

parentC::parentC()
{
  cout << "コンストラクタが呼ばれました" << endl;
}
parentC::~parentC()
{
  cout << "デストラクタが呼ばれました" << endl;
}

/*引数でオブジェクトを受け取る関数*/
void setObject(parentC tmp)
{
}

int main()
{
  parentC parentA;
  setObject(parentA);
  return 0;
}


戻り値としてオブジェクトを返す
戻り値としてオブジェクトを返すと、ローカルのオブジェクトは破棄され、コピーされたオブジェクトが生成され呼び出し元のオブジェクトにbit単位でコピーされる。

戻り値としてオブジェクトを返す例
#include <iostream>
using namespace std;

class parentC
{
public:
  parentC();
  ~parentC();
};

parentC::parentC()
{
  cout << "コンストラクタが呼ばれました" << endl;
}
parentC::~parentC()
{
  cout << "デストラクタが呼ばれました" << endl;
}

/*戻り値でオブジェクトを返す*/
parentC getObject()
{
  parentC ret;
  return(ret);
}

int main()
{
  parentC parentA;
  parentA = getObject();
  return 0;
}







Copyright 2007 ためになるホームページ All Rights Reserved.