2014年4月12日土曜日

開発環境

C++実践プログラミング (スティーブ オウアルライン (著)、Steve Oualline (原著)、Steve Oualline(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅣ部(高度なプログラミング概念)の18章(演算子のオーバーロード)、設問 18-1.を解いてみる。

その他参考書籍

設問 18-1.

コード(BBEdit, Emacs)

equal.cpp

#include <iostream>

class trouble {
public:
  int data;

  trouble();
  // コピーコンストラクタ
  trouble(const trouble& old);
  // 代入演算子のオーバーロード
  // 問題のコードでは引数の部分に&がない
  trouble operator = (const trouble& old_trouble);
};

// コンストラクタ
trouble::trouble() {
  data = 0;
}

// コピーコンストラクタ
// 代入演算子(以下のoperator =)を呼び出している
trouble::trouble(const trouble& old) {
  std::cout << "Copy constructor called\n";
  *this = old;
}

// 代入演算子のオーバーロード
// 問題のコードでは引数の部分に&がない
trouble trouble::operator = (const trouble& old_trouble)
{
  std::cout << "operator = called\n";
  data = old_trouble.data;
  return (*this);
}

int main(int argc, char *argv[])
{
  trouble trouble1;
  // コピーコンストラクタを呼び出す
  trouble trouble2(trouble1);
  // コピーコンストラクタを呼び出すと、代入演算子(operator =)が呼び出される
  // 問題のコードでは&が無いので、値渡しで引数trouble1が渡される(コピーが渡される)
  // すると、trouble1をコピーするのに、コピーコンストラクタが呼び出される
  // 無限循環

  return (0);
}

Makefile

#
# FSFのg++コンパイラ用のMakefile
#
CC=g++
CFLAGS=-g -Wall
all: equal

equal: equal.cpp
 ${CC} ${CFLAGS} -o equal equal.cpp

clean:
 rm equal

入出力結果(Terminal)

$ make && ./equal
g++ -g -Wall -o equal equal.cpp
Copy constructor called
operator = called
Copy constructor called
operator = called
…省略
Copy constructor called
operator  C-c C-c
$

Copy constructor calledは循環しなくなったけど、operator = calledでまた無限ループに。ということでもう少し修正してみることに。

コード(BBEdit, Emacs)

equal.cpp

#include <iostream>

class trouble {
public:
  int data;

  trouble();
  trouble(const trouble& old);
  // 問題のコードには、戻り値に&がない。
  trouble& operator = (const trouble& old_trouble);
};

// コンストラクタ
trouble::trouble() {
  data = 0;
}

// コピーコンストラクタ
trouble::trouble(const trouble& old) {
  std::cout << "Copy constructor called\n";
  *this = old;
}

// 代入演算子のオーバーロード
// 問題のコードには、戻り値に&がないので、戻り値を返すのに、
// (*this)のコピーを作成して、それを返す。つまり、コピーコンストラクタ
// が呼び出される。
// そして、コピーコンストラクタが呼び出される。なので無限ループになる
trouble& trouble::operator = (const trouble& old_trouble)
{
  std::cout << "operator = called\n";
  data = old_trouble.data;
  return (*this);
}

int main(int argc, char *argv[])
{
  trouble trouble1;
  trouble trouble2(trouble1);

  return (0);
}

入出力結果(Terminal)

$ make && ./equal
g++ -g -Wall -o equal equal.cpp
Copy constructor called
operator = called
$

0 コメント:

コメントを投稿