`print` function for an object with two different constructo

`print` function for an object with two different constructors

本文关键字:two different constructo with an print function for object      更新时间:2023-10-16

我有一个类Line,它有两个不同的构造函数:

// constructor - two points
Line::Line(Point& p1l, Point& p2l)
: p1(p1l), p2(p2l) {}
// constructor - point and vector
Line::Line(Point& pl, Vector& dirvec)
: p(pl), v(dirvec) {}

现在我正在尝试实现一个print函数,但遇到了问题。由于有两个构造函数具有两组不同的参数,我需要提前知道调用了哪个构造函数来创建Line,并尝试打印。但我不知道如何检查。构造函数的参数是其他类的对象,它们有自己的print函数。

// print function
void Line::print() const {
    cout << "Line[";
    p1.print();
    cout << ", ";
    if (p2) {
        p2.print();
    }
    else if (v) {
        v.print();
    }
    cout << "]";
}

我试图直接检查构造函数的参数是否存在,但它不起作用——我需要初始化print函数内的对象,这是一个错误的逻辑。

实现这种打印功能的最佳方式是什么?

似乎您的类包含四个字段:第一个构造函数为p1p2,第二个构造函数为带有vp

这种方法很糟糕,因为每次操作未初始化的字段时都应该消除它们之间的歧义(不仅在print函数中,而且每次都)。

我建议您选择以下解决方案之一:

保持startend

你必须改变你的构造函数如下:

Line::Line(const Point& start, const Point& end)
: start_(start), end_(end) {}
// constructor - point and vector
// You should implement operator+ (or a method) for vector and point.
Line::Line(Point& start, Vector& direction)
: start_(start), end_(start + direction) {}

保持start点和direction矢量:

// Point - Point should return a Vector. Or you could implement a Vector(Point, Point)
Line::Line(const Point& start, const Point& end)
: start_(start), direction_(end - start) {}
Line::Line(Point& start, Vector& direction)
: start_(start), direction_(direction) {}

您可以在成员变量中保存指示调用了哪个构造函数的信息。

class Line
{
    enum class ConstructionInfo : uint8_t
    {
        NONE = 0,
        TWO_POINTS = 1,
        POINT_DIRVECTOR = 2
    }
    ConstructionInfo _ci = ConstructionInfo::NONE;
}

然后在构造函数中初始化这个变量:

// constructor - two points
Line::Line(Point& p1l, Point& p2l)
: p1(p1l), p2(p2l), _ci(ConstructionInfo::TWO_POINTS) {}
// constructor - point and vector
Line::Line(Point& pl, Vector& dirvec)
: p(pl), v(dirvec), _ci(ConstructionInfo::POINT_DIRVECTOR) {}

然后在print()方法中:

switch(_ci)
{
case ConstructionInfo::TWO_POINTS:
    // print 2 points
    break;
case ConstructionInfo::POINT_DIRVECTOR:
    // print a point and a directing vector
    break;
}

也许您需要使用枚举类型来指示对象的类型。枚举变量可以在每个构造函数中进行不同的设置。

// constructor - two points
Line::Line(Point& p1l, Point& p2l)
: p1(p1l), p2(p2l), type(POINT_BASED) {}
// constructor - point and vector
Line::Line(Point& pl, Vector& dirvec)
: p(pl), v(dirvec), type(POINT_BASED) {}
// print function
void Line::print() const {
    cout << "Line[";
    p1.print();
    cout << ", ";
    if (type == POINT_BASED) {
        p2.print();
    }
    else if (type == VECTOR_BASED) {
        v.print();
    }
    cout << "]";
}

然而,如果它们真的有那么大的不同,也许您还应该考虑将类拆分为从BaseLine派生的两个类,每个类都有自己的打印函数。