2009-04-02 40 views
15

私はそれを取得しません。私は3時間コードを見ていて、問題は見えません。Visual C++で「利用可能なデフォルトコンストラクタがありません」というエラーが発生しました

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); 

私の議論のリストはかなり長いと知っていますが、その理由があります。おかげさまで

答えて

23

が使用する必要があります。

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; 
    } 
+2

しかし、それはデフォルトのctorではありません.Dirk(彼は優しく言った) –

+0

ありがとう、それは今働きます。誰かがそれがなぜ機能するのか説明できましたか?私はそれが親クラスのコンストラクタをどのように呼び出すのかは分かりません。私は何をしたのだろうと思った(親コンストラクタを単独で呼び出すとうまくいくだろう) ありがとう – chustar

+1

これは構文です:基本クラスを初期化リストから呼び出す必要があります。あなたが指定しなければ、コンパイラは、あなたが基本クラスのデフォルトのコンストラクタを呼び出すことを望んでいると考え、そのために問題を考えます。 – dirkgently

4

答えはdirkgentlyのことです。説明はC++の初期化シーケンスです。

クラスを構築するときは、すべての基本クラスが最初に構築されます。初期化リストのコンストラクタへの呼び出しを行うと、適切なコンストラクタが呼び出されます。基本クラスが初期化リストに表示されない場合は、デフォルトで構築されます。このすべてはの前に発生し、はコンストラクタブロック(中括弧)に入ります。

22

デフォルトのctorは、引数なしで呼び出すことができるものです。少なくとも、このコードでは、1つを持っていない:デフォルトのctorのは、署名

ClassName::ClassName(); 

を持っているのいずれかまたはすべての引数はデフォルト値を持っている必要があります。

しかし、構文についてのDirkのポイントは正しいと言いました。親クラスctorを呼び出す場合は、そのコロンの後に実行する必要があります。


@ dirkgentlyの答えは正しい構文を示していますが、それを少し拡張してみましょう。あなたは、2つのクラス

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の名前を付けるだけで、何もしません。あなたは

 Package foo = new 
     Package::Package(sName, sAddress, sState, sCountry, sZIP, 
          rName, rAddress, rState, rCountry, rZIP, 
          weight, cost); 

新しい演算子を使用して、クラスのパッケージの新しいオブジェクトを作成することもできますが、それはあなたがやりたいことはまだありません。あなたは を望んでいると、そのargリストを使用してTwoDayPackageのパッケージ部分を作成するようにC++に指示することです。コンパイラーは親クラスが何であるかを既に知っているので、完全修飾名を持つ必要はありません。

コンパイラが "井戸への複数のトリップ"のコードを生成するので、子ctorに値を割り当てることもできますが、それは非効率的です。だからC++には、Dirkが示したように、コロンの後にイニシャライザを置く特別な構文があります。

もう一つ:あなたはとにかくフラットにパラメータを割り当てているので、あなたがより多くのためのC++よくある質問Liteとの

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) 
{ 
} 

チェックthis sectionを言うことができます。

関連する問題