1

私は次のプログラムを持っています。これはオブジェクト指向であり、いくつかのオブジェクトを格納する構造'array'(私が定義した構造を使用する必要があるため、vector.hはカウントされません)を持っています。クラス関数と構造体はM.cpp(メイン)では問題なく機能しますが、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/////////

エラー:

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

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

4

2 に答える 2

1

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

于 2012-04-22T13:57:09.373 に答える
1

add関数テンプレートとを宣言していますがdummyData、非テンプレートを定義しています。

Array<Expe>汎用配列ではなく、これらの関数のみを処理する必要がある場合は、宣言を非テンプレートに変更します。

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

それらを汎用にする必要がある場合は、定義をヘッダーファイルに移動する必要があります。テンプレートは通常、それらを使用するすべてのソースファイルで使用できるように定義を必要とします。ただし、関数は特にで機能しているように見えるExpeので、テンプレートにはなりたくないと思います。

また、あなたのArrayタイプは三つのルールに違反しているため、使用するのは非常に危険です。std::vector動的配列を安全に管理するために使用してみませんか?

更新:あなたはそれをテンプレートのままにしてこれを行う方法を見たいと言います。そのためには、の明示的な特殊化が必要になりますExpe。これは次のようになります。

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

ヘッダーファイルで特殊化を宣言する必要があるかどうかは100%わかりません。こんなに変なことをしてから久しぶりなので、詳細はよくわかりません。確かに、汎用バージョンを実装する場合は、この特殊化を宣言する必要があります。それ以外の場合は、代わりに汎用バージョンが選択されます。いずれにせよ、の関数をオーバーロードする方が簡単ですArray<Expe>

于 2012-04-22T13:59:16.567 に答える