为什么需要使用声明命名构造函数

Why the need for a using-declaration naming a constructor?

本文关键字:构造函数 声明 为什么      更新时间:2023-10-16

C++11标准中的7.3.3.p1和p3两段都使用命名构造函数的声明引用了。为什么这是必要的?下面的代码显示了基类A的构造函数如预期的那样出现在派生类B中。

class A
{
    int i;
    public:
    A() : i(0) {}
    A(int i) : i(i) {}
};
class B : public A
{
    public:
//  using A::A;
    A f1() { return A(); }
    A f2() { return A(1); }
};
int main()
{
    B b;
    A a1 = b.f1();
    A a2 = b.f2();
}

如果我在上面注释掉using A::A;,则程序执行中没有任何变化。

这意味着从父类继承非默认构造函数,在本例中为A(int i)。主要更改您的申报,如:

int main()
{
    B b(42);  // Want to forward this to A::A(int)
    ...
}

如果没有using A::A子句,您将得到以下编译器错误(至少来自g++4.8.0):

co.cpp: In function ‘int main()’:
co.cpp:20:11: error: no matching function for call to ‘B::B(int)’
     B b(42);
           ^
co.cpp:20:11: note: candidates are:
co.cpp:10:7: note: B::B()
 class B : public A
       ^
co.cpp:10:7: note:   candidate expects 0 arguments, 1 provided
co.cpp:10:7: note: constexpr B::B(const B&)
co.cpp:10:7: note:   no known conversion for argument 1 from ‘int’ to ‘const B&’
co.cpp:10:7: note: constexpr B::B(B&&)
co.cpp:10:7: note:   no known conversion for argument 1 from ‘int’ to ‘B&&’

但是,如果您将using A::A声明添加回来,它会干净地编译。CCD_ 7最终调用CCD_ 8。