速習 CプログラマのためのC++プログラミング入門 サンプルプログラム集

コンピュータを学習する人の学校:パソコンキャンパス、プログラミングキャンパス

ここでは、 The Office Uchida, School of Computerの e-Learningシステム 「速習 CプログラマのためのC++プログラミング入門」のためのサンプルプログラムを紹介しています。

この中に記載されているプログラムをブラウズあるいはカットアンドペーストしてください。

目次に戻る


第5章 演算子のオーバーロード

内容
Sample list 5-1 点を加える例(メンバ関数版)
Sample list 5-2 点を加える例(+演算子版)
Sample list 5-3 コピーコンストラクタ
Sample list 5-4 コピーコンストラクタと関数呼び出しでのコピー
Sample list 5-5 複素数クラスの定義例(演算子の定義)
Sample list 5-6 複素数クラスの定義例(クラスの中でメンバ関数を定義している例)
Sample list 5-7 標準の複素数型

C++には、演算子を自分で定義する機能が含まれています。そのサンプル例です。効率はあまり考えておりません。

Sample list 5-1 点を加える例(メンバ関数版)point_cal1.cpp
#include <iostream>
using namespace std;

class Point
{
	int x, y;

public:
	Point( int, int );
	Point add( Point );
	void println();
};

Point::Point( int ax, int ay )
{
	this->x = ax;
	this->y = ay;
};

Point Point::add( Point p )
{
	Point q( this->x + p.x, this->y + p.y );

	return q;
}

void Point::println()
{
	cout << "(" << x << "," << y << ")" << endl;
}

int main()
{
	Point p0( 0, 0 ), p1( 1, 1 ), p2( 1, 2 ), p3( 0, 1 );

	p0 = p1.add( p2 );
	p0 = p0.add( p3 );

	p0.println();

	return 0;
}
Sample list 5-1の実行結果(cygwin)

% c++ point_cal1.cpp
% ./a
(2,4)

目次に戻る, 先頭に戻る


プログラム5-1をもっと見やすくするために、C++では、Pointクラス用の+演算子を定義することができます。

Sample list 5-2 点を加える例(+演算子版)point_cal2.cpp
#include <iostream>
using namespace std;

class Point
{
	int x, y;

public:
	Point( int, int );
	Point& operator=( const Point& x );
	Point operator+( const Point& x );
	void println();
};

Point::Point( int ax, int ay )
{
	this->x = ax;
	this->y = ay;
};

Point& Point::operator=( const Point& p )
{
	this->x = p.x;
	this->y = p.y;

	return *this;
};

Point Point::operator+( const Point& p )
{
	Point q( this->x + p.x, this->y + p.y );

	return q;
};

void Point::println()
{
	cout << "(" << x << "," << y << ")" << endl;
}

int main()
{
	Point p0( 0, 0 ), p1( 1, 1 ), p2( 1, 2 ), p3( 0, 1 );

	p0 = p1 + p2 + p3;

	p0.println();

	return 0;
}
Sample list 5-2の実行結果(cygwin)

% c++ point_cal2.cpp
% ./a
(2,4)

目次に戻る, 先頭に戻る


コピーコンストラクタを用いた例です。=演算子との呼び出しの違いを意識する必要があります。

Sample list 5-3 コピーコンストラクタpoint_cal3.cpp
#include <iostream>
using namespace std;

class Point
{
	int x, y;

public:
	Point( int, int ); // 通常のコンストラクタ
	Point( const Point& ); // コピーコンストラクタ
	Point& operator=( const Point& );
};

Point::Point( int ax, int ay )
{
	this->x = ax;
	this->y = ay;
};

Point::Point( const Point& p )
{
	cout << "copy constructor is called" << endl;
	this->x = p.x;
	this->y = p.y;
};

Point& Point::operator=( const Point& p )
{
	cout << "operator= is called" << endl;
	this->x = p.x;
	this->y = p.y;

	return *this;
};

int main()
{
	Point p0( 1, 2 );
	Point p1( 4, 5 );

	cout << "start program" << endl;

	Point p2 = p0;

	cout << "----------------" << endl;

	p1 = p2;

	return 0;
}
Sample list 5-3の実行結果(cygwin)

% c++ point_cal3.cpp
% ./a
start program
copy constructor is called
----------------
operator= is called

目次に戻る, 先頭に戻る


コピーコンストラクタと関数呼び出しでのコピー

Sample list 5-4 コピーコンストラクタと関数呼び出しでのコピーpoint_cal4.cpp
#include <iostream>
using namespace std;

class Point
{
	int x, y;

public:
	Point( int, int ); // 通常のコンストラクタ
	Point( const Point& ); // コピーコンストラクタ
	Point& operator=( const Point& );
};

Point::Point( int ax, int ay )
{
	this->x = ax;
	this->y = ay;
};

Point::Point( const Point& p )
{
	cout << "copy constructor is called" << endl;
	this->x = p.x;
	this->y = p.y;
};

Point& Point::operator=( const Point& p )
{
	cout << "operator= is called" << endl;
	this->x = p.x;
	this->y = p.y;

	return *this;
};

Point func( Point p )
{
	cout << "func is called" << endl;

	return p;
}

int main()
{
	Point p0( 1, 2 );
	Point p1( 4, 5 );

	cout << "start program" << endl;

	Point p2 = p0;

	cout << "1:----------------" << endl;

	p1 = p2;

	cout << "2:----------------" << endl;

	func( p2 );

	cout << "3:----------------" << endl;

	p1 = func( p2 );

	return 0;
}
Sample list 5-4の実行結果(cygwin)

% c++ point_cal4.cpp
% ./a
start program
copy constructor is called
1:----------------
operator= is called
2:----------------
copy constructor is called
func is called
copy constructor is called
3:----------------
copy constructor is called
func is called
copy constructor is called
operator= is called

目次に戻る, 先頭に戻る


複素数のサンプル例です。効率はあまり考えておりません。

Sample list 5-5 複素数クラスの定義例(演算子の定義)MyComplex.cpp
#include <iostream>
using namespace std;

class MyComplex
{
private:
	double re,im;
public:
	MyComplex(double r, double I);
	MyComplex& operator=( const MyComplex& x );
	MyComplex operator+( const MyComplex& x );
	MyComplex operator-( const MyComplex& x );
	MyComplex operator*( const MyComplex& x );
	MyComplex operator/( const MyComplex& x );
	MyComplex& operator+=( const MyComplex& x );
	MyComplex& operator+=( const double& x );
	MyComplex& operator-=( const MyComplex& x );
	MyComplex& operator-=( const double& x );
	MyComplex& operator*=( const MyComplex& x );
	MyComplex& operator*=( const double& x );
	MyComplex& operator/=( const MyComplex& x );
	MyComplex& operator/=( const double& x );
	MyComplex operator++( );
	MyComplex operator++( const int dummy );
	MyComplex operator--( );
	MyComplex operator--( const int dummy );
	bool operator==( const MyComplex& x );
	void print( ostream& os );
};

MyComplex::MyComplex(double r, double I)
{
	re=r;
	im=I;
};

MyComplex& MyComplex::operator=( const MyComplex& x )
{
	this->re = x.re;
	this->im = x.im;

	return *this;
};

MyComplex MyComplex::operator+( const MyComplex& x )
{
	MyComplex z( this->re + x.re, this->im + x.im );

	return z;
};

MyComplex MyComplex::operator-( const MyComplex& x )
{
	MyComplex z( this->re - x.re,  this->im - x.im);

	return z;
};

MyComplex MyComplex::operator*( const MyComplex& x )
{
	MyComplex z( this->re*x.re-this->im*x.im, this->im*x.re+this->re*x.im );

	return z;
};

MyComplex MyComplex::operator/( const MyComplex& x )
{
	MyComplex z( (this->re*x.re+this->im*x.im)/(x.re*x.re+x.im*x.im),
		         (this->im*x.re-this->re*x.im)/(x.re*x.re+x.im*x.im)  );

	return z;
};

MyComplex& MyComplex::operator+=( const MyComplex& x )
{
	this->re += x.re;
	this->im += x.im;

	return *this;
}

MyComplex& MyComplex::operator+=( const double& x )
{
	this->re += x;

	return *this;
}

MyComplex& MyComplex::operator-=( const MyComplex& x )
{
	this->re -= x.re;
	this->im -= x.im;

	return *this;
}

MyComplex& MyComplex::operator-=( const double& x )
{
	this->re -= x;

	return *this;
}

MyComplex& MyComplex::operator*=( const MyComplex& x )
{
	double r = this->re;
	double i = this->im;

	this->re = r*x.re - i*x.im;
	this->im = r*x.im - i*x.re;

	return *this;
}

MyComplex& MyComplex::operator*=( const double& x )
{
	this->re *= x;
	this->im *= x;

	return *this;
}

MyComplex& MyComplex::operator/=( const MyComplex& x )
{
	double r = this->re;
	double i = this->im;
	double denominator = x.re*x.re + x.im*x.im;

	this->re = ( r*x.re + i*x.im ) / denominator;
	this->im = ( i*x.re - r*x.im ) / denominator;

	return *this;
}

MyComplex& MyComplex::operator/=( const double& x )
{
	double r = this->re;
	double i = this->im;
	double denominator = x*x;

	this->re = ( r*x ) / denominator;
	this->im = ( i*x ) / denominator;

	return *this;
}
MyComplex MyComplex::operator++( ) // 前置演算子
{
	this->re++;

	return *this;
}

MyComplex MyComplex::operator++( const int dummy ) // 後置演算子
{
	MyComplex temp = *this;

	this->re++;

	return temp;
}

MyComplex MyComplex::operator--( ) // 前置演算子
{
	this->re--;

	return *this;
}

MyComplex MyComplex::operator--( const int dummy ) // 後置演算子
{
	MyComplex temp = *this;

	this->re--;

	return temp;
}

void MyComplex::print( ostream& os )
{
	os << "( " << this->re << "+" << this->im << "i )";
};

bool MyComplex::operator==( const MyComplex& x )
{
	return this->re == x.re && this->im == x.im;
}

ostream& operator<<(ostream& os, MyComplex& c )
{
	c.print( os );
	return os;
}

int main()
{
	MyComplex a = MyComplex(2,3);
	MyComplex b = MyComplex(4,5);
	MyComplex c = b;

	a = b + c;
	b = c + c*a;
	c += 1.0;

	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;

	MyComplex d = c++;

	cout << "c=" << c << ", d=" << d << endl;

	d = ++c;

	cout << "c=" << c << ", d=" << d << endl;

	if( a == b )
		cout << "same" << endl;
	else
		cout << "not same" << endl;

	return 0;
}
Sample list 5-5の実行結果(cygwin)

% c++ MyComplex.cpp
% ./a
a=( 8+10i )
b=( -14+85i )
c=( 5+5i )
c=( 6+5i ), d=( 5+5i )
c=( 7+5i ), d=( 7+5i )
not same

目次に戻る, 先頭に戻る


次の例は、クラス定義の中にメンバ関数のプログラムを含めたサンプル例です。

Sample list 5-6 複素数クラスの定義例(クラスの中でメンバ関数を定義している例)MyComplex.cpp
#include <iostream>
using namespace std;

class MyComplex
{
private:
	double re,im;
public:
	MyComplex(double r, double I) { re=r; im=I; };
	MyComplex& operator=( const MyComplex& x ) { this->re = x.re;  this->im = x.im; return *this; };
	MyComplex operator+( const MyComplex& x ) { MyComplex z( this->re + x.re, this->im + x.im ); return z; };
	MyComplex operator-( const MyComplex& x ) { MyComplex z( this->re - x.re,  this->im - x.im); return z; };
	MyComplex operator*( const MyComplex& x ) { MyComplex z( this->re*x.re-this->im*x.im, this->im*x.re+this->re*x.im ); return z; };
	MyComplex operator/( const MyComplex& x )
	{ MyComplex z( (this->re*x.re+this->im*x.im)/(x.re*x.re+x.im*x.im), (this->im*x.re-this->re*x.im)/(x.re*x.re+x.im*x.im)); return z; };
	void print( ostream& os ) { os << "( " << this->re << "+" << this->im << "i )"; };
};

ostream& operator<<(ostream& os, MyComplex& c )
{
	c.print( os );
	return os;
}

int main()
{
	MyComplex a = MyComplex(2,3);
	MyComplex b = MyComplex(4,5);
	MyComplex c = b;

	a = b + c;
	b = c + c*a;

	cout << "a=" << a << endl;
	cout << "b=" << b << endl;

	return 0;
}
Sample list 5-6の実行結果(cygwin)

% c++ MyComplex.cpp
% ./a
a=( 8+10i )
b=( -14+85i )

目次に戻る, 先頭に戻る


ちなみに、複素数は、C++には標準で用意されています。

Sample list 5-7 標準の複素数型ComplexSample.cpp
#include <iostream>
#include <complex>
using namespace std;


int main()
{
	complex<double> a(2,3);
	complex<double> b(4,5);
	complex<double> c = b;

	a = b + c;
	b = c + c*a;

	cout << "a=" << a << endl;
	cout << "b=" << b << endl;

	return 0;
}
Sample list 5-7の実行結果(cygwin)

% c++ MyComplex.cpp
% ./a
a=(8,10)
b=(-14,85)

目次に戻る, 先頭に戻る


Copyright (c) 2006 Satoshi Uchida, The Office Uchida, School of Computer