我不明白.我一直盯着代码代码三个小时,我看不出问题.
我正在创建的类叫做TwoDayPackage,它派生自一个名为Package的类.
这是我定义构造函数的方式:
TwoDayPackage(string, string, string, string, int, string, string, string, string, int, float, float, float);
这是我实现构造函数的方式:
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; }
这是我在我的主要功能中使用它的方式.
TwoDayPackage pack2(senderName, senderAddress, senderState, senderCountry, senderZIP, receipientName, receipientAddress, receipientState, receipientCountry, receipientZIP, weight, cost, 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; }
默认的ctor是可以不带参数调用的ctor.至少使用此代码,您没有:默认的ctor要么具有签名
ClassName::ClassName();
或者每个参数都必须有默认值.
也就是说,Dirk关于语法的观点是正确的; 如果你想调用父类ctor,你应该在冒号后执行.
@dirkgently的答案显示了正确的语法,但让我们稍微扩展一下.你有两节课
public class Package { // ... Package( /* that horrible ctor arg list */){/*...*/} // ... } public class TwoDayPackage : public Package { // ... TwoDayPackage(/* another horrible ctor */); // declaration only // ... }
然后你来定义它
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; }
......但那不起作用?为什么?基本上,因为你所说的C++没有意义:Package::Package
它只是命名超类的ctor并且没有对它做任何事情.您可以使用new运算符创建类Package的新对象,
Package foo = new Package::Package(sName, sAddress, sState, sCountry, sZIP, rName, rAddress, rState, rCountry, rZIP, weight, cost);
但那仍然不是你想要做的; 你想要的是告诉C++使用该arg列表构建TwoDayPackage的Package部分.您不需要具有完全限定名称,因为编译器已经知道父类是什么.
您也可以在子ctor中分配值,但这样效率很低,因为它使编译器生成"多次访问井"的代码.所以C++有一个特殊的语法,其中初始化器放在冒号后面,正如Dirk所示.
还有一件事:你可以说,因为你只是将参数分配到平面上
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) { }
有关更多信息,请查看C++ FAQ Lite的此部分.
答案是dirkgently.解释是C++中的初始化序列.
构造类时,首先构造所有基类.如果在初始化列表中提供对构造函数的调用,那么它将调用相应的构造函数.如果基类没有出现在初始化列表中,那么它将是默认构造的.所有这些都在进入构造函数块(花括号)之前发生.