具有两个不同构造函数的对象的`print`函数

时间:2015-06-26 07:56:17

标签: c++ constructor

我有一个包含两个不同构造函数的类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函数内初始化一个对象,这是一个错误的逻辑。

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

3 个答案:

答案 0 :(得分:3)

好像您的班级包含四个字段:p1p2代表第一个构造函数,p代表v代表第二个构建函数。

这种方法很糟糕,因为每次使用它们时都应该消除未初始化字段之间的歧义(不仅在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) {}

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

// 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的类 - 每个类都有自己的打印功能 - 如果它们确实不同的话。