2

我有一个关于在 C++ 中实现接口的问题:

假设有一个接口:

class A
{
 virtual void f() = 0;
};

在实现这一点时,我想知道是否有办法做类似的事情:

class B : public A {     
  void f(int arg=0) {....} // unfortunately it does not implement f() this way
};

我想保持 iterface 干净。当客户端代码通过公共接口 A 调用时,arg 总是自动设置为 0。但是,当我通过 B 调用它时,我可以灵活地调用它,并将 arg 设置为一些不同的值。它可以实现吗?

编辑:由于我控制接口和实现,我愿意接受任何建议、宏、模板、仿函数或任何其他有意义的东西。我只想拥有一个最小且干净的代码库。这个类很大,我不想编写任何非绝对必要的代码——例如,另一个简单地转发到实际实现的函数。

EDIT2:只是想澄清一下:公共接口提供给客户端。它比仅在内部使用的 B 类接口更具限制性。然而,函数 f() 基本上做同样的事情,除了基于输入 arg 的细微不同处理。真实类的接口函数比较多,签名比较复杂。快速进行函数转发会导致繁琐的代码重复,并且会污染 B 的内部接口。我想知道在 C++ 中处理这个问题的最佳方法是什么。

谢谢!

4

4 回答 4

2

是的,只需创建两个单独的函数:

class B : public A {     
    void f() { return f(0); }
    void f(int arg) { .... }
};
于 2013-09-07T16:26:18.997 回答
2

当你有一个接口时,基本原则应该是一个函数总是接受相同的参数并且总是以相同的方式操作,不管派生类在做什么。不允许添加额外的参数,因为这假定对对象进行操作的“事物”“知道”参数是/做什么。

有几种方法可以解决这个问题 - 立即浮现在脑海的是:

  1. 将参数添加到接口/基类。
  2. 不要使用参数,而是一些额外的功能,[当创建派生对象或“知道差异”的其他地方]将额外信息存储在需要它的对象内。
  3. 添加另一个“知道”类内部参数的类。

第二个例子是:

class B: public A
{  
   private:
     int x; 
   public:
     B() x(0) { ... }   // default is 0. 
     void f() { ... uses x ... }
     void setX(int newX) { x = newX; };
     int getX() { return x; }
};

因此,当您想使用x其他值而不是零时,您可以调用bobject->setX(42);或类似的方法。

于 2013-09-07T16:50:08.287 回答
0

From your descriptions I'd say you should provide two classes, both with a specific responsibility: One to implement the desired functionality, the other to provide the needed interface to the client. That way you separate concerns and dont violate the SRP:

class BImpl {
public:
  doF(int arg);  
};

class B : public A {
  BImpl impl;
public:
  virtual void f() override {
    impl.doF(0);
  }
};
于 2013-09-08T08:03:33.397 回答
0

快速进行函数转发会导致繁琐的代码重复,并且会污染 B 的内部接口。我想知道在 C++ 中处理这个问题的最佳方法是什么。

听起来您需要编写一个脚本来自动化部分过程。

于 2013-09-08T08:31:36.827 回答