为什么函数中的对象输入不匹配但仍然有效?

时间:2014-12-22 02:28:13

标签: c++ function class object

#include <iostream>

class A
{
public:
    A(int n = 0) : m_n(n)
    {
        std::cout << 'd';
    }
    A(const A& a) : m_n(a.m_n)
    {
        std::cout << 'c';
    }
private:
    int m_n;
};

void f(const A& a1, const A& a2 = A())
{}

int main()
{
    f(3);
}

任何机构都可以帮助解释以下内容

void f(const A &a1, const A &a2 = A())
{}

尤其是const A &a2 = A()

以及为什么f(3)?为什么整数输入仍然有效?应该是对象

3 个答案:

答案 0 :(得分:3)

因为传递参数,它会隐式转换为A。如果在整数ctor参数列表后键入explicit,它将不再执行此操作。

答案 1 :(得分:1)

  

任何机构都可以帮助解释以下内容

void f(const A &a1, const A &a2 = A()) {}

表达式const A&a1,表示 const引用对象类型A

表达式const A &a2 = A(),表示 const对象类型A的引用,如果未提供参数,则创建新的对象

使用你告诉编译器的const引用,不复制我的对象只是传递对它的引用这比使用void f(A a1, A a2 = A()) {}要便宜。在这种情况下,编译器将使用复制构造函数&#39; A(const A&amp; a)&#39;。

  

为什么f(3)?为什么整数输入仍然有效?应该是对象

这是由于构造函数A(int n = 0),编译器理解您要创建一个新的对象类型A对象,使用此构造函数并使用值3进行参数化。

答案 2 :(得分:1)

你接到了电话:

f(3);

函数f有一个默认参数,如果没有为第二个参数传递参数,它将使用该参数。所以你实际上的电话是:

f(3, A());

编译器将对第一个参数执行隐式转换,除非在构造函数之后使用关键字explicit。所以现在你的电话看起来像这样:

f(A(3), A());

因为您有用户创建的构造函数,所以不会为A获得自动生成的默认构造函数,但A(int n = 0)具有默认参数,并且由于没有传递参数,0将用作参数。所以你最后的电话是:

f(A(3), A(0));

这两个对象构造的A对象将在f函数的生命周期中存在,并被视为const个对象,因为函数定义将其参数声明为const