使用 C++ 基类构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8093882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using C++ base class constructors?
提问by minyor
While working with templates I ran into a need to make a base class constructors accessible from inherited classes for object creation to decrease copy/paste operations.
I was thinking to do this through using
keyword in same manner with functions case, but that not work.
在使用模板时,我遇到了让基类构造函数可以从继承类访问以创建对象以减少复制/粘贴操作的需要。我想通过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)'
}
So my question: Is there any way to import a base class constructors after new ones in inherited class been declared?
所以我的问题是:在继承类中的新构造函数被声明后,有没有办法导入基类构造函数?
Or there is only one alternative to declare new constructors and call a base ones from initializer list?
或者只有一种替代方法可以声明新的构造函数并从初始化列表中调用基本构造函数?
采纳答案by justin
Prefer initialization:
首选初始化:
class C : public A
{
public:
C(const string &val) : A(anInt) {}
};
In C++11, you can use inheriting constructors (which has the syntax seen in your example D
).
在 C++11 中,您可以使用继承构造函数(其语法在您的示例中D
)。
Update:Inheriting Constructors have been available in GCC since version 4.8.
更新:自 4.8 版以来,继承构造函数已在 GCC 中可用。
If you don't find initialization appealing (e.g. due to the number of possibilities in your actual case), then you might favor this approach for some TMP constructs:
如果您不觉得初始化有吸引力(例如,由于您实际情况中的可能性数量),那么您可能会喜欢这种方法用于某些 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;
}
回答by Sergei
Yes, Since C++11:
是的,从 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
};
For additional information see http://en.cppreference.com/w/cpp/language/using_declaration
有关其他信息,请参阅http://en.cppreference.com/w/cpp/language/using_declaration
回答by B?ови?
No, that's not how it is done. Normal way to initialize the base class is in the initialization list :
不,这不是这样做的。初始化基类的正常方法是在初始化列表中:
class A
{
public:
A(int val) {}
};
class B : public A
{
public:
B( int v) : A( v )
{
}
};
void main()
{
B b(10);
}
回答by obmarg
You'll need to declare constructors in each of the derived classes, and then call the base class constructor from the initializer list:
您需要在每个派生类中声明构造函数,然后从初始化列表中调用基类构造函数:
class D : public A
{
public:
D(const string &val) : A(0) {}
D( int val ) : A( val ) {}
};
D variable1( "Hello" );
D variable2( 10 );
C++11 allows you to use the using A::A syntax you use in your decleration of D, but C++11 features aren't supported by all compilers just now, so best to stick with the older C++ methods until this feature is implemented in all the compilers your code will be used with.
C++11 允许您使用在 D 的声明中使用的 using A::A 语法,但目前并非所有编译器都支持 C++11 功能,因此最好坚持使用旧的 C++ 方法直到此功能在您的代码将使用的所有编译器中实现。
回答by jbat100
Here is a good discussion about superclass constructor calling rules. You always want the base class constructor to be called beforethe derived class constructor in order to form an object properly. Which is why this form is used
这里有一个关于超类构造函数调用规则的很好的讨论。您总是希望在派生类构造函数之前调用基类构造函数,以便正确地形成一个对象。这就是为什么使用这种形式
B( int v) : A( v )
{
}