使用C++基类构造函数?

min*_*yor 50 c++ inheritance constructor c++11

在使用模板时,我遇到了一个需要,可以从继承的类访问基类构造函数来创建对象,以减少复制/粘贴操作.我想通过using关键字以与功能案例相同的方式做到这一点,但这不起作用.

class A
{
public: 
    A(int val) {}
};

class B : public A
{
};

class C : public A
{
public:
    C(const string &val) {}
};

class D : public A
{
public:
    D(const string &val) {}
    using A::A;              // g++ error: A::A names constructor
};

void main()
{
    B b(10);                // Ok.   (A::A constructor is not overlapped)
    C c(10);                // error: no matching function to call to 'C::C(int)'
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:在声明了继承类中的新构造函数后,有没有办法导入基类构造函数?

或者只有一个替代方法来声明新构造函数并从初始化列表中调用基础构造函数?

Ser*_*gei 58

是的,从C++ 11开始:

struct B2 {
    B2(int = 13, int = 42);
};
struct D2 : B2 {
    using B2::B2;
// The set of inherited constructors is
// 1. B2(const B2&)
// 2. B2(B2&&)
// 3. B2(int = 13, int = 42)
// 4. B2(int = 13)
// 5. B2()

// D2 has the following constructors:
// 1. D2()
// 2. D2(const D2&)
// 3. D2(D2&&)
// 4. D2(int, int) <- inherited
// 5. D2(int) <- inherited
};
Run Code Online (Sandbox Code Playgroud)

有关其他信息,请参阅http://en.cppreference.com/w/cpp/language/using_declaration

  • @charlesrockbass 这意味着您的 B2 没有与您的参数列表匹配的构造函数,或者构造函数无法访问 (2认同)

jus*_*tin 38

首选初始化:

class C : public A
{
public:
    C(const string &val) : A(anInt) {}
};
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,您可以使用继承构造函数(具有示例中所示的语法D).

更新:从4.8版开始,GCC中提供了继承构造函数.


如果您没有发现初始化的吸引力(例如,由于您实际情况下的可能性数量),那么您可能会对某些TMP结构采用这种方法:

class A
{
public: 
    A() {}
    virtual ~A() {}
    void init(int) { std::cout << "A\n"; }
};

class B : public A
{
public:
    B() : A() {}
    void init(int) { std::cout << "B\n"; }
};

class C : public A
{
public:
    C() : A() {}
    void init(int) { std::cout << "C\n"; }
};

class D : public A
{
public:
    D() : A() {}
    using A::init;
    void init(const std::string& s) { std::cout << "D -> " << s << "\n"; }
};

int main()
{
    B b; b.init(10);
    C c; c.init(10);
    D d; d.init(10); d.init("a");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


BЈо*_*вић 8

不,这不是它的完成方式.初始化基类的常规方法是在初始化列表中:

class A
{
public: 
    A(int val) {}
};

class B : public A
{
public:
  B( int v) : A( v )
  {
  }
};


void main()
{
    B b(10);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是更简洁和更清晰的答案. (2认同)