私は考えることができるようにしようとしているものの例の 'シンプルな'ものとして私は以下を持っています。私は抽象クラスA
を持っています。公開クラスは、operator==
とperformTasksSpecificToA
の2つのメソッドで公開されています。 A
のユーザーがA
の実装について心配する必要がないことを保証するために、「奇妙に繰り返されるテンプレートパターン」と同様に、「テンプレートメソッドパターン」を使用していることがわかります。つまり、AImpl
まだAImpl
という2つのインスタンスと同等かどうかをチェックすることができます。このアプローチに関するもう少し情報と文脈については、this answer on SOを参照してください。等価演算子定義で抽象クラスを使用しているときに、コードの重複を減らすために親クラスを定義するにはどうすればよいですか?
は今、私は次のようにクラスB
を定義したいとします
class B
{
public:
virtual ~B() = 0;
bool operator(const B& b) const;
void performTasksSpecificToB();
};
あなたはサブクラスを比較するための公共operator==
を定義するという点でA
として、クラスB
株式同じ問題を見ることができるように。 A
とB
の間にコードが重複しないように、親クラスを定義するにはどうすればLetter
と呼びますか?
私のコンパイルして実行する私の '簡単な例'です。
#include <iostream>
class A
{
public:
virtual ~A() = 0;
bool operator==(const A& a) const;
void performTasksSpecificToA();
private:
virtual bool checkEquality_(const A& a) const = 0;
};
template <class T>
class A_ : public A
{
protected:
bool checkEquality_(const A& a) const override;
private:
virtual bool checkEquality(const T& t) const = 0;
};
class AImpl : public A_<AImpl>
{
public:
AImpl(int val) : val(val){};
bool checkEquality(const AImpl& anAImpl) const override;
private:
int val;
};
A::~A(){}
bool A::operator==(const A& a) const{
return checkEquality_(a);
}
template <class T>
bool A_<T>::checkEquality_(const A& a) const{
const T* other = dynamic_cast<const T*>(&a);
if (other != nullptr){
const T& me = static_cast<const T&>(*this);
return other->checkEquality(me);
}
return false;
}
bool AImpl::checkEquality(const AImpl& anAImpl) const{
return val == anAImpl.val;
}
int main(){
// factory:
AImpl* aImpl1 = new AImpl(1);
AImpl* aImpl2 = new AImpl(2);
AImpl* aImpl3 = new AImpl(1);
// client:
A& A1 = *aImpl1;
A& A2 = *aImpl2;
A& A3 = *aImpl3;
std::cout << "A1 == A2 -> ";
std::cout << (A1 == A2 ? "true" : "false");
std::cout << std::endl;
std::cout << "A1 == A3 -> ";
std::cout << (A1 == A3 ? "true" : "false");
std::cout << std::endl;
delete aImpl1;
delete aImpl2;
delete aImpl3;
return 0;
}
なぜ等価比較でこのようなレベルの間接参照がありますか? –
最初のレベルは 'A'をテンプレートクラスにすることを避けるためです:したがって、私は実際のロジックを' A_'に移動しました。 2番目のレベル、すなわち 'A :: checkEquality_'を使用するのは、公に公開されたメソッドと、サブクラスによって(「テンプレートメソッドパターン」ごとに)ライドされる必要のある部分とを区別するためです。 – wesanyer