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/////////

错误:

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

我尝试了所有我能想到的...上网,但仍然找不到该参考错误的原因。

4

2 回答 2

1

Looks like the version of dummyData you've provided in ListStruct.cpp is not considered as a full specialization of a templated version. So, compiler is unable to find it. You should define it as a template<> void dummyData<Expe>(Array<Expe>&).

于 2012-04-22T13:57:09.373 回答
1

You are declaring function templates add and dummyData, but defining non-templates.

If you only need these functions to work on Array<Expe> rather than on generic arrays, then change the declarations to non-templates:

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

If they need to be generic, then you'll have to move the definitions into the header file; templates usually need the definition to be available in every source file that uses them. However, your functions appear to be working specifically with Expe, so I don't think they do want to be templates.

Also, your Array type is breaking the Rule of Three, making it very dangerous to use. Why don't you use std::vector to manage the dynamic array safely?

UPDATE: You say you want to see how to do this while keeping it a template. To do that, you'll need an explicit specialisation for Expe. That would look something like this:

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

I'm not 100% sure whether or not you'd also need to declare the specialisation in the header file; it's a long time since I've done anything this weird, so I'm not quite sure of the details. Certainly, if you implement the generic version, then you will have to declare this specialisation; otherwise the generic version will be chosen instead. In any event, it's simpler just to overload the function for Array<Expe>.

于 2012-04-22T13:59:16.567 回答