未命名的默认参数可防止出现歧义

时间:2013-11-16 20:57:56

标签: c++

我有一个类,它包含一些基于某些配置的(持久)摄像头。各种类与集合相关联,并且集合提供了与实际实现的各种接口。每个摄像机用户都以自己的方式与集合相关联(人们几乎可以认为它与自己的集合相关联,但实现可能会巩固所有责任,例如:

#include <memory>
#include <map>

enum eCameraType{ eCameraType_IR, eCameraType_HDTV };
template <class CameraIF>
struct CameraCollectionIF
{
  virtual CameraIF& camera( eCameraType, typename CameraIF::Tag = typename CameraIF::Tag() ) = 0;

  protected:
    ~CameraCollectionIF(){}
};

struct CameraControlIF_A
{
  struct Tag{};
  virtual void doX() = 0;
};
struct CameraControllerA
{
  void foo()
  {
    //Gets the camera in terms of responsibility associated with
    // applicable control IF, but other classes can get camera (control) in
    // terms of their responsibility, and that without ambiguity...
    collection_->camera( eCameraType_HDTV ).doX();
  }

  std::shared_ptr<CameraCollectionIF<CameraControlIF_A>> collection_;
};

struct CameraControlIF_B
{
  struct Tag{};
  virtual void doY() = 0;
};
struct CameraControllerB
{
  void foo()
  {
    //Gets the camera in terms of responsibility associated with
    // applicable control IF, but other classes can get camera (control) in
    // terms of their responsibility, and that without ambiguity...
    collection_->camera( eCameraType_IR ).doY();
  }

  std::shared_ptr<CameraCollectionIF<CameraControlIF_B>> collection_;
};

//Now implementation of actual collection...

struct Camera : CameraControlIF_A, CameraControlIF_B
{
  //etc...
};

struct CameraCollectionForConfigurtionX :
  CameraCollectionIF<CameraControlIF_A>,
  CameraCollectionIF<CameraControlIF_B>
{
  private:
    //Assume for now all camera types shall exist in map, therefore lookup can't
    // fail...
    virtual CameraControlIF_A& camera( 
      eCameraType cameraID, CameraControlIF_A::Tag ) override
    {
      return( *cameras_[cameraID] );
    }
    virtual CameraControlIF_B& camera( 
      eCameraType cameraID, CameraControlIF_B::Tag ) override
    {
      return( *cameras_[cameraID] );
    }
    //etc...
    std::map<eCameraType, std::unique_ptr<Camera>> cameras_;
};

// Other configurations may exist that hold different collection of cameras....

可以说上面提到的基本原理,但它确实提供了各种控制器和它们的摄像机之间的分离,而与系统的配置无关。

我的问题是:

由于虚拟函数“camera”从未通过集合的公共接口调用,我认为没有必要指定默认参数与base的相同,实际上,可以省略它完全是:

virtual CameraIF& camera( 
  eCameraType, typename CameraIF::Tag = typename CameraIF::Tag() ) = 0;

VS

virtual CameraControlIF_A& camera( 
  eCameraType cameraID, CameraControlIF_A::Tag );

添加到有关默认参数的问题,是上面提到的防止模糊重载(在实现中)常见的技术吗?

1 个答案:

答案 0 :(得分:1)

当重写使用基类中的默认参数声明的virtual函数时,可以添加另一个默认参数, 甚至可以具有不同的值!但是,在覆盖函数中指定默认参数是一个非常糟糕的主意,因此使用不同的值。在任何情况下,您都不需要指定默认值,但 do 需要采用相应的参数,否则它不是重写函数:作为覆盖的函数必须匹配完全基类声明(除非返回类型是指针或引用,否则它可以是协变的)。在C ++中(自2011年修订版以来),您还可以使用override [contextual]关键字跟随覆盖声明,以使编译器验证声明确实是覆盖。