2

私は C++ を初めて使用し、等式などのバイナリ メソッドと組み合わせてデータの抽象化を理解するのに苦労しています。インターフェイスを定義したい

class A {
 public:
  static A* Make(int);
  virtual ~A() {};
  virtual bool Eq(A*) = 0;
};

ファクトリ パターンを使用して、実装を非表示にできます。

class B : public A {
 public:
  B(int x) : x_(x) {}

  bool Eq(A* a) {
    return x_ == dynamic_cast<B*>(a)->x_;
  }

 private:
  int x_;
};

A* A::Make(int x) {
  return new B(x);
}

次に、抽象化を使用できます。

A* a = A::Make(1);
A* b = A::Make(2);

if (a->Eq(b)) {
  cout << "Yes!" << endl;
} else {
  cout << "No!" << endl;
}

ただし、動的キャストはさまざまな理由で最悪です。私が見た最大の問題は、A を C でサブクラス化し、型 C のオブジェクトを a->Eq に渡すことができることです。これにより、未定義の動作が発生します。コードが両方のオブジェクトのプライベート メンバーにアクセスできるようにバイナリ メソッドを定義する方法がわかりません。私の直感では、ビジター パターンを使用してこれを行うことができますが、解決策を思い付くことができませんでした。

MLを知っている人のために、私は基本的に次のことをしたいと思っています:

module A : sig
  type t
  val make: int -> t
  val eq: t -> t -> bool
end = struct
  type t = int
  let make x = x
  let eq x y = (x = y)
end
4

4 に答える 4

2

等値関数を仮想にしたくありません。

次に例を示します。

class Animal
{
  public:
    virtual bool is_equal(const Animal * p_a) = 0;
};

class Human : public Animal
{
  public:
    bool is_equal(const Animal * p_a);
};

class Toad : public Animal
{
  public:
    bool is_equal(const Animal * p_a);
};

動物へのポインターの 2 つの変数を作成すると、次のようになります。

   Animal * p_animal_human = new Human;
   Animal * p_animal_toad  = new Toad;

仮想is_equalメソッドを使用すると、2 つの動物クラスを比較できます。

   if (p_animal_human->is_equal(p_animal_toad)

Humanこれにより、一連の実行時エラーが発生する可能性があり、この例のように、 a が aと等しいことを比較したくありませんToadHuman2 つのインスタンスまたは 2つのインスタンスを比較したい場合がありToadます。

上記のifステートメントでは、Animal両方のクラスに共通のデータのみが比較されます。

StackOverflow で「[C++] slicing」という用語を検索してください。

于 2013-08-31T17:31:55.187 に答える
0
  • 「コードが両方のオブジェクトのプライベート メンバーにアクセスできるようにバイナリ メソッドを定義する方法がわかりません」
  • C++ では、friend キーワードを使用して、別のクラスまたはオブジェクト型からプライベート メンバー関数およびプロテクト メンバー関数にアクセスできます。
  • 次のようなヘッダー ファイルに、プライベート メンバー関数または保護されたメンバー関数を含むクラスを含める必要があります。
  • クラスA {
  • 友人クラス B;
  • }
  • また、その逆もできます。したがって、クラス B はクラス A のフレンドになり、クラス A はクラス B のフレンドになることができます。
于 2013-08-31T22:21:23.950 に答える