如何在类构造函数中解决“重定义默认参数”

时间:2016-02-02 13:01:46

标签: c++ constructor

考虑以下示例:

class Rectangle{
    Rectangle(int x, int y, int width, int height);
    Rectangle(int topLeft_x, int topLeft_y, int bottomRight_x, int bottomRight_y);    
};

可以构建一个Rectangle对象,给出(x,y)坐标加上宽度和高度,或给出左上角点对和右下角点对。

虽然从面向对象的角度来看这是正确的,但这不是从编译器的角度来看,返回错误“已定义或声明的成员函数”

虽然我通常在成员函数的情况下很容易解决这个问题,但只需根据它的作用更改名称,这对构造函数来说是不可能的。

解决此问题的简单而正确的方法是什么,同时保留构造对象的方法?

3 个答案:

答案 0 :(得分:2)

另一种可能的解决方案(除了@VladfromMoscow建议的那对)是一种执行构造的静态方法。这允许您为它们提供不同的名称,因为它们的参数列表非常相似。 Thisi被称为Named Constructor Idiom

class Rectangle
{
 public:
   static Rectangle createRectangle(int x, int y, int width, int height) 
   {
      return Rectangle(x,y,width,height);
   }
   static Rectangle createRectangleCorners(int x1, int y1, int x2, int y2) 
   {
      return Rectangle(x1,y1,x2-x1, y2-y1); 
   }
 private:
   // Doesn't have to be private, but this forces users to use the above 
   // constructors
   Rectangle(int x, int y, int width, int height);
}

答案 1 :(得分:1)

你自己写的

  

左上角积分对和右下角积分

所以你需要的是定义类Point并在构造函数声明中使用这个类型。

否则构造函数声明为

class Rectangle{
    Rectangle(int, int, int, int);
    Rectangle(int, int, int, int);    
};

正如您所看到的那样,即使您要编写多行注释,这些声明也没有意义。:)

另一种方法是声明第一个构造函数,如

class Rectangle{
    Rectangle(int x, int y, unsigned int width, unsigned int height);
    Rectangle(int topLeft_x, int topLeft_y, int bottomRight_x, int bottomRight_y);    
};

然而,这种方法是不安全的,因为必须输入指定为第三个或第四个参数的每个整数文字。

您可以使用标准类Point而不是类std::pair。例如

#include <utility>

//...

class Rectangle{
    Rectangle(int x, int y, int width, int height);
    Rectangle( const std::pair<int, int> &topLeft, const std::pair<int, int> &bottomRight);    
};

答案 2 :(得分:1)

如何解决此问题的另一种方法是使用Tag dispatching

不要使用具有不同名称的方法,而是给它们一个新参数,例如,

&#13;
&#13;
struct useCorners {};
struct useDimension {};

class Rectangle
{
    Rectangle(useCorners, int topLeft, int topRight, int bottomLeft, int bottomRight) 
    { ...
    }
    Rectangle(useDimension, int topLeft, int topRight, int width, int height) 
    { ... 
    }
};
&#13;
&#13;
&#13;