Visual C++ 中的“没有合适的默认构造函数可用”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/710432/
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
"No appropriate default constructor available" error in Visual C++
提问by chustar
I don't get it. I've been staring at the code the code for three hours and I can't see the problem.
我不明白。我一直盯着代码代码三个小时,我看不出问题。
The class I'm creating, called TwoDayPackage is derived from a class called Package.
我正在创建的名为 TwoDayPackage 的类派生自名为 Package 的类。
This is how I defined the constructor:
这就是我定义构造函数的方式:
TwoDayPackage(string, string, string, string, int, string, string, string, string, int, float, float, float);
This is how I implement the constructor:
这就是我实现构造函数的方式:
TwoDayPackage::TwoDayPackage(string sName, string sAddress, string sState, string sCountry, int sZIP, string rName, string rAddress, string rState, string rCountry, int rZIP, float weight, float cost, float flat)
{
Package::Package(sName, sAddress, sState, sCountry, sZIP, rName, rAddress, rState, rCountry, rZIP, weight, cost);
flatRate = flat;
}
This is how i use it in my main function.
这就是我在主函数中使用它的方式。
TwoDayPackage pack2(senderName, senderAddress, senderState, senderCountry, senderZIP, receipientName, receipientAddress, receipientState, receipientCountry, receipientZIP, weight, cost, flat);
I know my argument list is pretty long, there's a reason for that. Thanks.
我知道我的论点列表很长,这是有原因的。谢谢。
回答by dirkgently
Should use:
应该使用:
TwoDayPackage::TwoDayPackage(string sName, string sAddress, string sState, string sCountry, int sZIP, string rName, string rAddress, string rState, string rCountry, int rZIP, float weight, float cost, float flat)
:Package(sName, sAddress, sState, sCountry, sZIP, rName, rAddress, rState, rCountry, rZIP, weight, cost)
{
flatRate = flat;
}
回答by Charlie Martin
A default ctor is one that can be called with no arguments. At least with this code, you don't have one: a default ctor either has the signature
默认构造函数是可以不带参数调用的构造函数。至少使用此代码,您没有:默认构造函数要么具有签名
ClassName::ClassName();
or every argument must have a default.
或者每个参数都必须有一个默认值。
That said, Dirk's point about the syntax is correct; if you want to invoke the parent classes ctor, you should do it after that colon.
也就是说,德克关于语法的观点是正确的;如果你想调用父类ctor,你应该在那个冒号之后做。
@dirkgently's answer shows the right syntax, but let's expand it a little bit. You've got two classes
@dirkgently 的答案显示了正确的语法,但让我们稍微扩展一下。你有两节课
public class Package {
// ...
Package( /* that horrible ctor arg list */){/*...*/}
// ...
}
public class TwoDayPackage : public Package {
// ...
TwoDayPackage(/* another horrible ctor */); // declaration only
// ...
}
and then you come along to define it
然后你来定义它
TwoDayPackage::TwoDayPackage(string sName, string sAddress,
string sState, string sCountry,
int sZIP, string rName,
string rAddress, string rState,
string rCountry, int rZIP,
float weight, float cost, float flat)
{
Package::Package(sName, sAddress, sState, sCountry, sZIP,
rName, rAddress, rState, rCountry, rZIP,
weight, cost);
flatRate = flat;
}
... but that doesn't work? Why? Basically, because what you're telling C++ doesn't make sense: the Package::Package
is just naming the superclass's ctor and not doing anything with it. You could create a new object of class Package by using the newoperator,
......但这不起作用?为什么?基本上,因为您告诉 C++ 的内容没有意义:Package::Package
只是命名超类的 ctor 而没有对它做任何事情。您可以使用new运算符创建类 Package 的新对象,
Package foo = new
Package::Package(sName, sAddress, sState, sCountry, sZIP,
rName, rAddress, rState, rCountry, rZIP,
weight, cost);
but that's still not what you want to do; what you wantis to tell C++ to contruct the Package parts of TwoDayPackage using that arg list. You don't need to have the fully-qualified name, because the compiler already knows what the parent class is.
但这仍然不是你想做的;您想要的是告诉 C++ 使用该 arg 列表构造 TwoDayPackage 的 Package 部分。您不需要具有完全限定的名称,因为编译器已经知道父类是什么。
You could also just assign values in the child ctor, but that's inefficient, as it makes the compiler generate code for "multiple trips to the well". So C++ has a special syntax where initializers are put after a colon, as Dirk showed.
您也可以只在子 ctor 中分配值,但这效率低下,因为它使编译器生成“多次到井”的代码。所以 C++ 有一个特殊的语法,初始化器放在冒号之后,正如 Dirk 所展示的。
One more thing: since you're just assigning a parameter to flat anyway, you can say
还有一件事:既然你只是为 flat 分配了一个参数,你可以说
TwoDayPackage::TwoDayPackage(string sName, string sAddress,
string sState, string sCountry,
int sZIP, string rName,
string rAddress, string rState,
string rCountry, int rZIP,
float weight, float cost, float flat) :
Package(sName, sAddress, sState, sCountry, sZIP,
rName, rAddress, rState, rCountry, rZIP, weight, cost),
flatRate(flat)
{
}
Check this sectionof the C++ FAQ Lite for more.
查看C++ FAQ Lite 的这一部分了解更多信息。
回答by David Rodríguez - dribeas
The answer is that of dirkgently. The explanation is the initialization sequence in C++.
答案是直接的。解释是C++中的初始化顺序。
When constructing a class, all base classes are constructed first. If you provide a call to the constructor in the initialization list, then it will call the appropriate constructor. If the base class does not appear in the initialization list, then it will be default constructed. All this happens beforeentering the constructor block (curly braces).
构造类时,首先构造所有基类。如果您在初始化列表中提供对构造函数的调用,那么它将调用适当的构造函数。如果基类没有出现在初始化列表中,那么它将被默认构造。所有这些都发生在进入构造函数块(花括号)之前。