2012-04-22 2 views
1

다음 프로그램이 있습니다. 그것은 객체 지향이며, 구조체 '배열'을 가지고 있습니다. (어떤 구조체를 사용해야하는데, vector.h는 계산하지 않습니다) 그래서 어떤 객체를 저장합니다. Class 함수와 구조는 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 : 오류 : '<'토큰 앞에 예상 초기화 자 –