2009-06-08 4 views
0

C++을 사용하고 있으며 템플릿 기반 클래스 (스택)를 만들려고합니다. 복사 생성자와 대입 연산자를 정의하고 싶습니다.템플릿 클래스를 컴파일 할 때 "클래스에 선언 된 멤버 함수가 없습니다"오류가 발생합니다.

헤더에 정의 된 다음 cpp 파일에서 정의됩니다. '스택 : 스택 (CONST 스택 &)는'클래스 '스택' 을 일치하지 않습니다에 대한 프로토 타입 - assignement 연산자의 경우 : - 복사 생성자를 들어 :

여기에 내가 얻을 수있는 문제는 스택 .cpp : 28 : 오류 : 아니요 '스택 & Stack :: operator = (const Stack &)'클래스 'Stack'에 선언 된 멤버 함수 stack.cpp : 4 : error : candidate is : Stack : : Stack()

다음은 헤더 파일입니다.

여기,

// stack.cpp 

#include "stack.hpp" 

template <class T> 
Stack<T>::Stack() : 
    v_(0), 
    vsize_(10), 
    vused_(0) 
{ 
    v_ = new T[vsize_]; 
} 

template <class T> 
Stack<T>::~Stack() 
{ 
    delete[] v_; 
} 


// Stack(const Stack&); 
template <class T> Stack<T>::Stack(const Stack<T>& other) : 
    v_(NewCopy(other.v, other.vsize_, other.vsize_)), 
    vsize_(other.vsize_), 
    vuser_(other.vused) 
{ 
} 

// Stack& operator=(const Stack&); 
template<class T> Stack<T>& Stack<T>::operator=(const Stack<T>& other) 
{ 
    if (this != &other) 
    { 
    T* v_new = NewCopy(other.v_, other.vsize_, other.vsize__; 
    delvete v_; 
    v_ = v_new 
    vsize_ = other.vsize_; 
    vused_ = other.vused_; 
    } 
    return *this 

} 

마지막 한가지하여 컴파일의 로그입니다 : 여기

// stack.hpp 

#ifndef STACK_HPP 
#define STACK_HPP 


#include <stdio.h> 
#include <assert.h> 


template <class T> 
class Stack 
{ 

public: 
    Stack(); 
    ~Stack(); 

    Stack(const Stack&); 
    Stack& operator=(const Stack&); 


private: 
    T* v_; 
    size_t vsize_; 
    size_t vused_; 

}; 

은 CPP 파일입니다 나는 이것이 단지 작은 오타 오류입니다 확신

g++ -c stack.cpp -o stack.o 
stack.cpp:20: error: prototype for ‘Stack<T>::Stack(const Stack<T>&)’ does not match any in class ‘Stack<T>’ 
stack.cpp:4: error: candidate is: Stack<T>::Stack() 
stack.cpp:28: error: no ‘Stack<T>& Stack<T>::operator=(const Stack<T>&)’ member function declared in class ‘Stack<T>’ 

하지만 그럴 수 없어 그것을 찾은 것 같습니다. 도움을 주셔서 감사합니다.

답변

4

템플릿을 별도의 컴파일 단위로 컴파일 할 수 없습니다. 즉, 모든 템플릿 코드는 모두 하나의 헤더에 있어야합니다. 이것은 문제의 원인이 될 가능성이 큽니다.

이유는 템플릿이 실제 클래스를 정의하지 않기 때문입니다. 템플릿은 코드 생성 방법을 지정합니다.

Stack<int>::Stack<int>(const Stack<int>& src); 

이 완전히 정의하는

Stack<float> 

보다 완전히 다른 유형이 : 그래서 당신이 할 때

Stack<int> myStack; 

컴파일러는 복사 생성자를 생성하는 템플릿을 사용 독립적 인 복사본 생성자, 그리고 완전히 독립적 인 메소드 세트를 제공합니다.

많은 옵션 중 하나는 역순으로 헤더에 cpp를 포함하는 것입니다. 바닥

#include "Stack.cpp" 

하지만 가죽의 종류 정말 그 모든 하나의 헤더에 풍덩 사실에 Stack.hpp에서

.

+0

고마워요! 난 몰랐어. 나는 그것을 바꿨고 몇 가지 오류를 수정 한 후에 작동한다. 잘 이해한다면 헤더와 템플릿 기반 클래스의 구현을 구분할 수있는 방법이 없습니까? 아마도 인터페이스를 사용 하시겠습니까? – Arthur

+0

예 템플릿을 사용하여 상속을 사용하고 공통 기본 클래스 (스택 및 스택 모두가 IStack에서 상속)를 상속 할 수 있습니다. 이것은 다소 유용 할 수 있습니다. –

+1

분리가 제대로 작동하고 제시된 코드가 컴파일되어 있어야합니다 (버그를 발견하지 못했습니다). 인스턴스화하는 데 사용할 유형을 미리 아는 경우 .cpp 파일에서 명시 적으로 인스턴스를 생성하고 코드를 숨길 수 있습니다. 그러나 일반적으로 템플릿 선언 자체와 모든 파일의 멤버 함수를 포함하는 동일한 파일에서 템플릿 정의를 갖습니다. –

관련 문제