如何解决类构造函数中的"redefinition of default parameter"

How to workaround "redefinition of default parameter" in class constructor

本文关键字:redefinition of parameter default 构造函数 何解决 解决      更新时间:2023-10-16

请考虑以下示例:

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

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

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

虽然我通常在成员函数的情况下轻松修复此条件,但只需根据它的作用更改名称,这对于构造函数来说是不可能的。

解决此问题

的更简单和正确的方法是什么,同时保持构造对象的两种方式?

另一种可能的解决方案(除了@VladfromMoscow建议的对之外)是执行构造的静态方法。 这使您可以为它们指定不同的名称,因为它们的参数列表非常相似。 thisi 被称为命名构造函数习语

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

你自己已经写了

左上点对和右下角点

因此,您需要的是定义类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);    
};

但是,此方法不安全,因为必须强制转换指定为第三个或第四个参数的每个整数文本。

您可以使用标准类std::pair代替类Point。例如

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

解决此问题的另一种方法是使用标记调度:

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

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) 
    { ... 
    }
};