【问题标题】:Why the object input in the function does not match but still work?为什么函数中输入的对象不匹配但仍然有效?
【发布时间】:2014-12-22 02:28:12
【问题描述】:
#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 &amp;a2 = A()

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

【问题讨论】:

    标签: c++ function class object


    【解决方案1】:

    因为在传递参数时,它被隐式转换为A。如果你在整数 ctor 参数列表后面输入explicit,它就不会再这样做了。

    【讨论】:

    • 附录:经验法则:除非您真的确定,否则请创建一个参数-ctors explicit。也可以考虑那里的默认参数。
    • 对此进行扩展:f(3);f( A(3) ); 相同,编译器将尝试为每个构造函数执行此操作(实际上,通常函数调用会发生同样的事情,而不仅仅是构造函数电话)
    • @Deduplicator 真的吗?我实际上喜欢隐式转换。也许对于原始类型,标记为显式是一个好习惯(例如,我不想在使用 int 构造时意外传递数组),但对于其他所有类型,我让它保持隐式。
    • 只有在你真的确定它不会是错误的转换时才隐含,所以不要丢弃任何信息。
    【解决方案2】:

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

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

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

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

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

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

    这是由于构造函数A(int n = 0),编译器明白你想创建一个新的对象类型A对象,使用这个构造函数并参数化值为3。

    【讨论】:

      【解决方案3】:

      你有你的电话:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多