2011-01-12 7 views
1

これは私を狂ってしまった。私は「WordCloud :: WordCloud()」関数にエラーが発生しました。デフォルトのコンストラクタが呼び出されているようですが、定義していないため、エラーがスローされていました。C++ - なぜこのメンバを静的宣言する必要がありますか?

コンストラクタは次のとおりです。

WordCloud(map<string, int> *source); 

そしてメインのCPPファイル内

は、エラーがときにインスタンス化されていた私はWordCloudオブジェクトを推測している、

class FontTestingApp : public AppBasic 
{          // <-- error was appearing on this line 
public: 
    void setup(); 
    void mouseDown(MouseEvent event); 
    void update(); 
    void draw(); 

    map<string, int> wordList; 
    WordCloud wc;  // comment out this line and it compiles 
}; 

ので、指示された回線に発生しましたFontTestingAppクラスがインスタンス化されました。

私は

WordCloud wc; 

が、それはコンパイル行をコメントアウトした場合。それを修正する

私は最終的に

static WordCloud wc; 

にラインを変更し、それがコンパイル。

私は本当に理由は分かりませんが、それは十分ではありません:)誰かがここで何が起こっているのか説明できたら、私はとても感謝しています。私はlibCinderを途中で使用しています(libcinder.org

+0

これはctor宣言です。空のctorを実装しようとしましたか? – mingos

+0

staticを追加した後、あなたの 'main'に' FontTestingApp'のオブジェクトを作成してもまだ動作しますか? – Jaywalker

+0

いいえ、静的を追加するとコンパイルされますがリンクされません。他の人が指摘したように、静的は問題を隠すだけです。問題はもっと基本的だった。私はwcをWordCloud * - WordCloud * wcとして宣言していたはずです。宣言することによって、私はインスタンス化しているので、既定のコンストラクタを呼び出すことができます。私はかなり愚かな気分になる:)私はJavaであまりにも多くの年を非難する... – Sam

答えて

1

カスタムコンストラクタ(WordCloud用)を用意しているので、コンパイラはデフォルトのctorを生成しなくなりました。

WordCloudがあなたのクラスでない場合は、すべてのコンストラクタ(クラスFontTestingAppのデフォルトのものも含めて)を使用して、イニシャライザリストに正しくメンバーを作成する必要があります。

+0

カスタムコンストラクタは3のルールの一部ではありません。 –

+0

@Oli、知っている、私は私のansを編集する必要があります "あなたが独自のカスタムコンストラクタを定義した場合、3つのルールに従う"、私はリンクを探して気を散らした。 – Nim

+0

私はそうは思わない;ルール3は完全に別の問題です。 –

1

コンパイラがデフォルトのコンストラクタを探していた理由は正しいですか。 FontTestingAppコンストラクタ内のイニシャライザリスト内の関連するWordCloudコンストラクタを明示的に呼び出さないでください。

staticのアプローチが「機能する」理由は?それはしません。静的メンバーの宣言には、定義を伴う必要があります(通常、CPPファイル内のWordCloud FontTestingApp::wc(/*args*/);の行に沿って、オブジェクトがインスタンス化されず、コンストラクタも呼び出されません)。

注:静的クラスメンバのセマンティクスは、非常にで、非スタティックメンバのセマンティクスとは異なります。

+0

Ack、みなさんありがとうございます。私はこれが長すぎるに違いないと思うし、最近Javaで時間を過ごしている。私の間違いはとても馬鹿だった。私は、WordCloud * wcというポインタを宣言しました。 *私はポインタ変数を作成していなかったので、私は暗黙のうちに単語クラウドをインスタンス化していました。私は馬鹿のように感じる。すべての回答者に感謝します。答えは非常に参考になります。 – Sam

0

デフォルト以外のコンストラクタを定義する必要があります。静的でなければ、明示的に(宣言とは反対に)定義するまでメモリは割り当てられません。なぜなら、おそらくエラーが発生しなかったからです。

5

クラス内の非静的メンバー変数は、包含オブジェクトの構築時にインスタンス化されます(つまり、そのコンストラクタが呼び出されます)。デフォルトでは、引数のないデフォルトのコンストラクタが呼び出されますが、コンパイラは明示的なコンストラクタを指定しない場合にのみこれを提供します。

溶液は、明示的にFontTestingAppコンストラクタでwcオブジェクトを構築することである。

static変更はエラー、オブジェクトをインスタンス化しない クラス定義で宣言 static WordCloud wc;を抑制理由について
FontTestingApp::FontTestingApp() 
    : wc(&wordList) 
{ /* ... */ } 

。ファイルスコープのextern WordCloud wc;がクラスをインスタンス化しないのとまったく同じ方法で宣言します。確かに、静的メンバ変数は、基本的に自分の名前とアクセス制御ルールは、彼らがしているクラスに基づいていることを除いてexternグローバル、同じです

あなたが実際にいくつかの.cppファイルで静的メンバ変数をインスタンス化持っていた:。

WordCloud FontTestingApp::wc; 

これでエラーが発生しました。あなたがすべてで変数をインスタンス化していない場合は、他の場所でそれを参照しようとした場合、あなたはもちろん、リンカエラーを取得すること

static map<string, int> dummy_word_source; 
WordCloud FontTestingApp::wc(&dummy_word_source); 

注:もちろん、あなたがこの問題を解決するためにコンストラクタのパラメータに渡すことができます。

+0

非常にはっきりした答え - おはようbdonlan – Sam

0

問題は、私が推測していることは、WordCloudクラスにはデフォルトコンストラクタがないことです。したがって、コンパイラがFontTestingAppのデフォルトのコンストラクタを自動的に生成すると、WordCloudデータメンバの存在しないコンストラクタ、つまりコンパイラエラーを呼び出そうとします。

WordCloudメンバの静的マスクをマークしますが、スタティックデータメンバは圧縮器で初期化されていないため、この問題は修正されません。そのため、あなたのコードは変更でコンパイルできました。

この問題を解決するには、メンバー初期化リストを使用してWordCloudデータメンバーの適切なコンストラクターを呼び出すFontTestingAppクラスのコンストラクターを指定します。

0

wcメンバーを静的にしないでください。

あなたは、代わりにこのように、FontTestingAppコンストラクタの初期化リストから明示的に自分のクラスのコンストラクタを呼び出す必要があります:

FontTestingApp::FontTestingApp(): wc(&wordList) { 
    // more initialization 
} 
1

を使用すると、パラメータなしのパラメータとしたいの使用コンストラクタを持つコンストラクタを宣言する場合は、明示的に最後を宣言する必要があります。しかし、あなたはwcコンストラクタをパラメータで使用しません。あなたがこれを行うたい場合は、このような何か書く必要があります:「静的」文を使用して

class FontTestingApp : public AppBasic 
{         
    public: 
... 
    FontTestingApp() : wc(&wordList) {} 
    map<string, int> wordList; 
    WordCloud wc;  
}; 

のみデータメンバの宣言ではなく、定義です。そのため、あなたのコードはエラーなしでコンパイルされます。

関連する問題