2012-04-22 15 views
1

次のプログラムがあります。これはオブジェクト指向であり、構造体 '配列'(私が定義した構造体を使用しなければならないので、vector.hはカウントしません)をいくつかのオブジェクトを格納する場所に置いています。クラス関数と構造体はM.cpp(main)でうまく動作しますが、controller.cppからそれらを呼び出そうとすると参照エラーが発生します。異なるモジュールから関数を呼び出す - 参照エラー

ListStruct.h:

template <class T> 
struct Array{ 
    int days; 
    T * M; 

    Array(int size) : days(size), M(new T[size]) 
    { 
    } 
    ~Array() 
    { 
     delete[] M; 
    } 
}; 

void currentDay(); 

template <class T> 
void add(int,int,Array<T> &); 

template <class T> 
void dummyData(Array<T> &); 

ListStruct.cpp

#include <stdlib.h> 
#include <iostream> 
#include <ctime> 

#include "ListStruc.h" 
#include "Expe.h" 

using namespace std; 

int currDay; 

void currentDay(){ 
    time_t t = time(0); // get time now 
    struct tm * now = localtime(& t); 
    ::currDay = now->tm_mon + 1; 
} 

void add(int cant, int type,Array <Expe> &A){ 
    //Adds to current day the amount to a specific type 
    int newVal; 
    newVal = A.M[currDay].getObj(type); 
    newVal += cant; 
    A.M[currDay].editObj(type,newVal); 

} 

void dummyData(Array <Expe> &A){ 
    for(int i=0; i<31; i++){ 
     A.M[i].Expe::setObj((i*3),(i*1),(i*6),(i*2),(i*4),(i*5)); 
    } 
} 

M.cpp - プログラムの主な機能:

#include <iostream> 

#include "Expe.h" 
#include "ListStruc.h" 
#include "Controller.h" 

using namespace std; 
int main(){ 
//Main function of the program. no pre/ post condition. 

Array <Expe> A(31); // Work space 
Array <Expe> B(31); // Backup space 

cout<<&A; // testing for allocation 
cout<<&B; 

Expe a; 
a.setObj(5,5,5,5,5,5); // checking class functions 
a.printObj(); 

A.M[1]=a; 
A.M[1].printObj(); 

//check dummy FOR-, WORKS! 
for(int i=0; i<31; i++){ 
    A.M[i].Expe::setObj((i*3),(i*1),(i*6),(i*2),(i*4),(i*5)); 
} 

a.editObj(3,100); 
a.printObj();  // check objects calling, WORKS! 
cout<<"Obj A.[10]:"; 
A.M[10].printObj(); 
cout<<endl<<"Obj A.[29]:"; 
A.M[29].printObj(); 

    dummyData(A); ///////ERROR///////// 

ERROR:

D:\c++\Begin\Lab3-5_OOP\Debug/../M.cpp:44: undefined reference to `void dummyData<Expe>(Array<Expe>&)' 

私は考えることができるすべてを試みました...インターネットをサーフィンしても、その参照エラーの理由を見つけることができませんでした。

答えて

1

ファンクションテンプレートadddummyDataを宣言していますが、非テンプレートを定義しています。

あなただけの、非テンプレートに宣言を変更し、Array<Expe>ではなく、一般的な配列上で動作するように、これらの機能が必要な場合:

class Expe; 
void add(int,int,Array<Expe> &); 
void dummyData(Array<Expe> &); 

、彼らは汎用的である必要があれば、あなたが移動する必要がありますヘッダファイルへの定義。テンプレートは通常、定義を使用するすべてのソースファイルで使用可能にする必要があります。しかし、あなたの関数は具体的にはExpeで動作しているように見えるので、テンプレートであるとは思っていません。

また、ArrayタイプはRule of Threeを破っています。使用することは非常に危険です。 std::vectorを使ってダイナミックアレイを安全に管理してみませんか?

更新:これをテンプレートとして保持する方法を確認したいとします。そのためには、Expeの明示的な専門化が必要です。それは次のようになります。

template <> void dummyData(Array<Expe> &) { 
    // your Expe version goes here 
} 

私はあなたにもヘッダファイルに特殊化を宣言する必要があるだろうかどうかを100%わかりません。私はこの奇妙なことを何度もやって以来、長い時間を要しています。確かに、汎用バージョンを実装する場合は、この特殊化を宣言する必要があります。それ以外の場合は、汎用バージョンが代わりに選択されます。いずれにしても、Array<Expe>の関数をオーバーロードするだけで簡単です。

+0

私が知っている限り、テンプレート化された関数の完全な専門化があれば、手を加えて.cppファイルの中に隠します。私が間違っている? :) – parallelgeek

+0

そして、私はティがどのような方法であるかに基づいてテンペストされることを望んでいると仮定できますか?あなたは私に例を示すことができますか? –

+0

@parallelgeek:はい、そうすることはできますが、ポイントはありません。オーバーロードによって同じ結果がより簡単に得られます。 –

1

ListStruct.cppで提供しているdummyDataのバージョンは、テンプレートバージョンの完全な特殊化とは見なされません。したがって、コンパイラはそれを見つけることができません。 template<> void dummyData<Expe>(Array<Expe>&)と定義する必要があります。

+0

エラー: .. \/ListStruc.h:34:27:エラー: '<'トークンの前に期待されるイニシャライザ –

関連する問題