2016-10-27 15 views
1

、これはここでは例えば、既にカバーされています:static array class variable "multiple definition" C++複数の定義C++

をしかし、私はここにいくつかの詳細をしないのです。 Foo.cpp

#include <iostream> 
#include "Model.h" 

    int main(int argc, char** argv){ 
     std::cout << "hello" << std::endl; 
     return 0; 
    } 

Model.h

#ifndef MODEL_H 
#define MODEL_H 

#include <string> 
#include "md2Loader.h" 

class Model{ 
    public: 
    Model(); 
    Model(const std::string& model_file); 

    private: 
    md2_header_t header; 
    modelData_t model; 
}; 

#endif 

Model.cpp

#include "Model.h" 
#include "md2Loader.h" 

Model::Model(){} 

Model::Model(const std::string& model_file){ 
    model = md2Loader::load_model(model_file); 
} 

とmd2Loader.h

#ifndef MD2LOADER_H 
#define MD2LOADER_H 

struct modelData_t{ 
    int numVertices; 
    int numTextures; 
    // etc 
}; 

struct md2_header_t { 
    std::string version; 
}; 

class md2Loader{ 
public: 
    md2Loader(){}; 
    static modelData_t load_model(const std::string& model_file); 
}; 

modelData_t md2Loader::load_model(const std::string& model_file){ 
    modelData_t result; 
    result.numVertices = 1000; 
    result.numTextures = 10; 

    return result; 
} 


#endif 

私は、次のクラスを持っています

リンカーは、複数の定義を文句を言います。しかし、私は確信していません、なぜ。 #ifndef、#defineプリプロセッサディレクティブは役に立ちませんか?私はmd2Loader.hがModel.cppとModel.hの両方に含まれるようにしています。 Model.hで実装を行い、Model.cppを離れたままにしておくと、コンパイルとリンクが正常に行われます。私は、プリプロセッサの指示が起こるのを防ぐと思っていましたが、明らかに私はそこに何かを見逃しています。

+1

あなたは_ヘッダファイル – Danh

+0

で定義された 'inline'機能に必要な「#ifndefの、の#defineプリプロセッサディレクティブは助けないのですか?」_ノー –

答えて

5

inlineヘッダファイルに定義されている関数を使用するか、ソースファイルに移動する必要があります。その機能は複数の翻訳単位で表示されるためです。

inline modelData_t md2Loader::load_model(const std::string& model_file){ 
    modelData_t result; 
    result.numVertices = 1000; 
    result.numTextures = 10; 
    return result; 
} 

限り、各定義は異なる翻訳に表示されるプログラムで(C++ 17以降)インライン関数または変数の複数の定義が存在してもよいinline specifier

の詳細を見ます単位。例えば、インライン関数またはインライン変数(C++ 17以降)は、複数のソースファイルに#includeされているヘッダファイルで定義されているかもしれません。

+0

ありがとう!その背後にある理論へのリンクを教えてください。 Javaの背景からくると、これは私にとってはちょっと混乱することがあります... – kimsay

+0

@kimsayはもう少しのドキュメントを追加しました – Danh

+0

@kimsay 'inline'は異なる翻訳単位にするための機能としてマークしています。 ODRを使用すると、コンパイラは、複数の定義がすべて同一であると判断し、それらを統合できます。 Javaには '#include'がありませんので、最初に問題が発生することはありません。 –