考虑以下示例:
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)坐标加上宽度和高度,或给出左上角点对和右下角点对。
虽然从面向对象的角度来看这是正确的,但这不是从编译器的角度来看,返回错误“已定义或声明的成员函数”
虽然我通常在成员函数的情况下很容易解决这个问题,但只需根据它的作用更改名称,这对构造函数来说是不可能的。
解决此问题的简单而正确的方法是什么,同时保留构造对象的方法?
答案 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:
不要使用具有不同名称的方法,而是给它们一个新参数,例如,
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;