我是C++的新手,并且正在努力与二进制方法(例如,相等性)结合来理解数据抽象。我想定义一个接口(interface)

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;
}

但是,动态转换很糟糕,原因有很多。我看到的最大问题是,可以用C继承A的子类,然后将类型为C的对象传递给a-> Eq,这将导致未定义的行为。我无法弄清楚如何定义一个二进制方法,以使代码可以访问两个对象的私有(private)成员。我的直觉是,可以使用访问者模式来完成此操作,但是我无法提出解决方案。

对于那些了解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

最佳答案

扩展我的评论,您可以使用PIMPL(实现的指针)惯用法编写代码,如下所示:

在您的头文件(a.hpp)中

class A
{
public:
   A(int);
   ~A();
   bool Eq(const A& a) const;

private:
   class AImpl;
   AImpl* implementation_;
};

在执行文件(a.cpp)中
struct A::AImpl {
   AImpl(int x) : x_(x) {}
   int x_;
};

A::A(int x)
   : implementation_(new AImpl(x))
{}

A::~A()
{
   delete implementation_;
}

bool
A::Eq(const A& rhs) const
{
   return implementation_->x_ == rhs.implementation_->x_;
}

在您的主文件中
#include "a.hpp"

int main()
{
   A one(1);
   A two(2);

   return one.Eq(two);
}

因为所有实际代码都在实现文件中,所以您无法从其他类(仅包含头文件a.hpp)中看到它。为了清楚起见,我使用了原始指针,但在实际设置中,您将需要使用适当的智能指针。

关于c++ - C++中的数据抽象和二进制方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18550621/

10-09 13:29