今、勉強のためにケント・ベックの"テスト駆動開発入門"を再読しております。
本はJavaとPythonの例が載っているのですが、仕事でC++しか使っていないので、C++でそれらの例を書き直しながら読み進めております。
そこで、わからないところがありました。
Moneyクラスから継承したDollarクラスとFrancクラスがあります。
Moneyクラスはprotectedなint型のメンバのamount_をもっております。
Moneyクラスはequalsメソッドを備えており、amount_の値が等しく、二つのオブジェクトのgetClass()の結果が等しい場合にのみtrueを返します。
これを実装しようとして以下のコードを書きました。
#include <iostream> #include <typeinfo> #include <memory> class Money{ public: Money(int amount) : amount_(amount){} virtual ~Money(){} virtual bool equals(const Money* money) const; protected: int amount_; }; bool Money::equals(const Money* money) const{ std::cout << "EQUALS" << std::endl; std::cout << "this : " << typeid(this).name() << std::endl; std::cout << "money : " << typeid(money).name() << std::endl; return amount_ == money->amount_ && typeid(this) == typeid(money); } class Dollar : public Money{ public: Dollar(int amount) : Money(amount){} }; class Franc : public Money{ public: Franc(int amount) : Money(amount){} }; int main(){ std::shared_ptr<Dollar> dollar(new Dollar(10)); std::shared_ptr<Franc> franc(new Franc(10)); std::cout << "MAIN" << std::endl; std::cout << "dollar : " << typeid(dollar.get()).name() << std::endl; std::cout << "franc : " << typeid(franc.get()).name() << std::endl; dollar->equals(franc.get()); return 0; }
すると結果がこうなりました
MAIN dollar : P6Dollar franc : P5Franc EQUALS this : PK5Money money : PK5Money
環境はg++ 4.5.3です。
問題はequalsでthisも比較対象のmoneyもMoneyクラスとして認識されてしまうことです。
本のサンプルコードではここでgetClass()を使い、thisがDollarとして、moneyがFrancとして認識されるので二つのオブジェクトのamount_の値が等しくてもそれらの価値は異なるという結果になります。
なぜequalsでDollarだったthisもFrancだったmoneyもMoneyとして認識されてしまうのか、と
equalsの場所でthisをDollarとして、moneyをFrancとして認識する方法があるのかという2点に関して、教えていただけないでしょうか?