情報処理5レポート課題(10)の解答例

更新:2009年7月27日


  1. レポート課題(9)の解答例を出発点として (自作のプログラムがあればそれを出発点として)、 複素数クラス,有理数クラスにおいて 四則演算を関数呼出の代わりに演算子を用いることができるようにし、 また、複素数クラスについては実数との演算、 有理数クラスについては整数との演算を行うことができるようにしてください。
    complex.h
    class Complex{
     private:
    	double Re, Im;
     public:
    	Complex(void);
    	Complex(const double &re);
    	Complex(const double &re, const double &im);
    	const double re(void) const;
    	const double im(void) const;
    	void print(void) const;
    };
    
    const Complex operator+(const Complex &lhs, const Complex &rhs);
    const Complex operator-(const Complex &lhs, const Complex &rhs);
    const Complex operator*(const Complex &lhs, const Complex &rhs);
    const Complex operator/(const Complex &lhs, const Complex &rhs);
    
    complex.cxx
    #include<iostream>
    #include<cstdlib>
    #include"complex.h"
    
    Complex::Complex(void){
    }
    
    Complex::Complex(const double &re): Re(re), Im(0.0){
    }
    
    Complex::Complex(const double &re, const double &im): Re(re), Im(im){
    }
    
    void Complex::print(void) const{
      std::cout << "(" << Re << ")+i(" << Im << ")" << std::endl;
      return;
    }
    
    const double Complex::re(void) const{
      return Re;
    }
    
    const double Complex::im(void) const{
      return Im;
    }
    
    const Complex operator+(const Complex &lhs, const Complex &rhs){
    	Complex result(
    		       lhs.re()+rhs.re(),
    		       lhs.im()+rhs.im()
    		       );
    	return result;
    }
    
    const Complex operator-(const Complex &lhs, const Complex &rhs){
    	return Complex (
    		       lhs.re()-rhs.re(),
    		       lhs.im()-rhs.im()
    		       );
    }
    
    const Complex operator*(const Complex &lhs, const Complex &rhs){
    	double re=lhs.re()*rhs.re()-lhs.im()*rhs.im();
    	double im=lhs.re()*rhs.im()+lhs.im()*rhs.re();
    	Complex result(re, im);
    	return result;
    }
    
    const Complex operator/(const Complex &lhs, const Complex &rhs){
    	if(rhs.re()==0.0 && rhs.im()==0.0){
    		std::cout << "Division by 0" << std::endl;
    		exit(1);
    	}
    	double re=(lhs.re()*rhs.re()+lhs.im()*rhs.im())/(rhs.re()*rhs.re()+rhs.im()*rhs.im());
    	double im=(lhs.im()*rhs.re()-lhs.re()*rhs.im())/(rhs.re()*rhs.re()+rhs.im()*rhs.im());
    	return Complex(re, im);
    }
    
    main_complex.cxx
    #include<iostream>
    #include<cstdlib>
    #include"complex.h"
    
    int main(void){
    	Complex x(2.0, 3.1), y(-1.2, 3.4), z(5.6, 7.8), u(-9.1, 2.3), result;
    	std::cout << "x="; x.print();
    	std::cout << "y="; y.print();
    	result=x+y;
    	std::cout << "result=x+y="; result.print();
    	result=x-y;
    	std::cout << "result=x-y="; result.print();
    	result=x*y;
    	std::cout << "result=x*y="; result.print();
    	result=x/y;
    	std::cout << "result=x/y="; result.print();
    	result=x+y*x/z-u;
    	std::cout << "result=x+y*x/z-u="; result.print();
    	result=0.1-x*y+0.2;
    	std::cout << "result=0.1-x*y+0.2="; result.print();
    	return 0;
    }
    
    fraction.h
    class Fraction{
     private:
    	int Denominator, Numerator;
     public:
    	Fraction(void);
    	Fraction(const int &numerator);
    	Fraction(const int &numerator, const int &denominator);
    	const int denominator(void) const;
    	const int numerator(void) const;
    	void print(void) const;
    };
    
    const Fraction operator+(const Fraction &lhs, const Fraction &rhs);
    const Fraction operator-(const Fraction &lhs, const Fraction &rhs);
    const Fraction operator*(const Fraction &lhs, const Fraction &rhs);
    const Fraction operator/(const Fraction &lhs, const Fraction &rhs);
    
    fraction.cxx
    #include<iostream>
    #include"fraction.h"
    
    Fraction::Fraction(void){
    }
    
    Fraction::Fraction(const int &numerator): Numerator(numerator), Denominator(1){
    }
    
    Fraction::Fraction(const int &numerator, const int &denominator): Numerator(numerator), Denominator(denominator){
    }
    
    const int Fraction::denominator(void) const{
      return Denominator;
    }
    
    const int Fraction::numerator(void) const{
      return Numerator;
    }
    
    void Fraction::print(void) const{
    	std::cout << "(" << Numerator << ")/(" << Denominator << ")";
    	return;
    }
    
    const Fraction operator+(const Fraction &lhs, const Fraction &rhs){
    	int denominator=lhs.denominator()*rhs.denominator();
    	int numerator=lhs.denominator()*rhs.numerator()+lhs.numerator()*rhs.denominator();
    	return Fraction(numerator, denominator);
    }
    
    const Fraction operator-(const Fraction &lhs, const Fraction &rhs){
    	Fraction result;
    	int denominator=lhs.denominator()*rhs.denominator();
    	int numerator=rhs.denominator()*lhs.numerator()-rhs.numerator()*lhs.denominator();
    	return Fraction(numerator, denominator);
    }
    
    const Fraction operator*(const Fraction &lhs, const Fraction &rhs){
      return Fraction(
    		  lhs.numerator()*rhs.numerator(),
    		  lhs.denominator()*rhs.denominator()
    		  );
    }
    
    const Fraction operator/(const Fraction &lhs, const Fraction &rhs){
    	return Fraction(
    			lhs.denominator()*rhs.numerator(),
    			lhs.numerator()*rhs.denominator()
    	);
    }
    
    main_fraction.cxx
    #include<iostream>
    #include"fraction.h"
    
    int main(void){
    	Fraction x(2, 3), y(-1, 3), z(3, 5),
    		u(-2, 7), result;
    	std::cout << "x="; x.print(); std::cout << std::endl;
    	std::cout << "y="; y.print(); std::cout << std::endl;
    	result=x+y;
    	std::cout << "result=x+y="; result.print(); std::cout << std::endl;
    	result=x-y;
    	std::cout << "result=x-y="; result.print(); std::cout << std::endl;
    	result=x*y;
    	std::cout << "result=x*y="; result.print(); std::cout << std::endl;
    	result=x/y;
    	std::cout << "result=x/y="; result.print(); std::cout << std::endl;
    	result=y*x/z+u;
    	std::cout << "result=y*x/z+u="; result.print(); std::cout << std::endl;
    	result=1+y*x-2;
    	std::cout << "result=1+y*x-2="; result.print(); std::cout << std::endl;
    	return 0;
    }
    
  2. 次について書籍やWebを調べてそれぞれ回答してください。
    1. データメンバをprivateに宣言する理由を述べてください。
    2. 浅いコピーと深いコピーの違いを述べてください。
    3. const参照引数の利点を述べてください。
    4. 与えられたプログラムからコンストラクタが定義されている箇所を見つける指針を述べてください。
    5. メンバ関数と非メンバ関数の違いを、その性質、宣言・定義のしかたの観点から述べてください。

    解答例は省略されています.ただし,以下に皆様の解答を匿名で列挙しますので, 復習に役立てて下さい.

na1/