繁体   English   中英

C ++中的函数默认参数

[英]Function Default Parameters in C++

我在求职面试中被问到这个问题,即使在编写之后,我仍然不明白结果......

我有以下课程:

class Point
{
    public:
    Point(double x = 0, double y = 0) { m_X = x; m_Y = y; }

    double m_X, m_Y;
};

和main.cpp是:

int main()
{
    double a = 1, r = 1, xCoord = 5, yCoord = 7;

    Point p = (a+r*xCoord , a+r*yCoord);

    cout<<"X = "<<p.m_X<<" Y = "<<p.m_Y<<endl;

    return 0;
}

类p的数据成员获取值:

m_X = a+r*yCoord, m_Y = 0

现在,为什么呢?

由于逗号运算符和非显式构造函数。 表达式(a + r * xCoord , a + r * yCoord)是逗号运算符的应用程序,其值为a + r * yCoord ,现在Point构造函数的单参数隐式形式与此值一起使用,第二个参数是默认的。

您可以通过使构造函数explicit来防止此类错误进入,这通常建议用于可以使用一个参数调用的任何构造函数,除非您确实需要隐式转换。

要获得所需的行为,您需要直接初始化:

Point p(a + r * xCoord, a + r * yCoord);

这是一个棘手的问题......表达

(a+r*xCoord , a+r*yCoord)

comma operator表达式,因此您的代码实际上是

Point p = a+r*yCoord;

构造函数可以用作转换构造函数(因为它不是explicit ),因此它与写入相同:

Point p(a+r*yCoord, 0);

要获得“预期结果”,您应该删除等号并写入

Point p(a+r*xCoord , a+r*yCoord);

一般来说,最好使用两个不同的构造函数,而不是依赖于默认参数,例如:

struct P2d {
    double x, y;
    P2d() : x(0), y(0) { }
    P2d(double x, double y) : x(x), y(y) { }
};

你应该总是特别注意只带一个参数的构造函数(或者你只能传递一个参数,就像在你的例子中一样),因为除非它们被声明为explicit否则C ++可以隐式地使用它们进行转换,有时候会以令人惊讶的方式使用它们。

最后一点是,奇怪的是代码中使用的逗号运算符没有产生警告,因为第一个表达式没有副作用,编译器应该能够检测到这可能是一个错误。

Point p = (a+r*xCoord , a+r*yCoord);

(表达式)使用comma operator ,它按顺序计算所有项,返回最右边。

正确的形式将是

auto p = Point(a+r*xCoord , a+r*yCoord);
Point p(a+r*xCoord , a+r*yCoord);

你可能想要改变

Point p = (a+r*xCoord , a+r*yCoord);

Point p (a+r*xCoord , a+r*yCoord);

前者使用逗号运算符为您提供一个值(您在逗号运算符表达式中的最后一个值),然后将其分配给您的对象,这将设置您的x成员并将您的y成员默认为零。

后者将使用两个参数调用构造函数。

这是因为您正在使用转换运算符,是Point double 当使用拷贝初始化(初始化用=符号),则表达式到的右侧=首先被转换到该类型的左侧,然后拷贝构造被使用(在概念上,至少)。 使用复制初始化无法指定多个参数。 所以右边的表达式是(a + r*xCoord, a + r*yCoord) 逗号是逗号运算符 (不是逗号标点符号),它用于评估其左手参数,然后是右手参数,并为结果提供右手参数的结果。 (并且左手参数的结果被丢弃了。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM