Проблема с шаблонным классом

Модераторы: Romeo, Hawk, Absurd, WinMain, DeeJayC

Ответить
Аватара пользователя
Monopo
Сообщения: 119
Зарегистрирован: 06 дек 2007, 20:08
Откуда: Linux

Проблема с шаблонным классом

Сообщение Monopo » 15 апр 2009, 17:40

Пытаюсь собрать, да не получается.
Makefile:

Код: Выделить всё

MASSIV: complex.o massiv.o main.o
	g++ -o MASSIV complex.o massiv.o main.o //ошибка здесь при финальной сборке

main.o: main.cpp
	g++ -c main.cpp

massiv.o: massiv.cpp
	g++ -c massiv.cpp

complex.o: complex.cpp
	g++ -c complex.cpp

clean:
	rm -f *.o MASSIV
complex.cpp

Код: Выделить всё

#include <stdio.h>
#include <string.h>
#include "iostream"
#include <stdlib.h>

using namespace std;

class Complex
{
	public:
	int Re;
	int Im;
	Complex():Re(0),Im(0){};
	Complex(const int& tre,const int& tim):Re(tre),Im(tim){};
	Complex(const Complex&obj):Re(obj.Re),Im(obj.Im){};
	friend ostream& operator<<(ostream&,const Complex&);		
	friend istream& operator>>(istream&,const Complex&);
};

ostream& operator<<(ostream& out,const Complex& Tc)
{
	//..
}

istream& operator>>(istream& in,Complex& Tc)
{
	//..
}
complex.h:

Код: Выделить всё

#ifndef _COMPLEX_H_
#define _COMPLEX_H_

#include <stdio.h>
#include <string.h>
#include "iostream"
#include <stdlib.h>

using namespace std;

class Complex
{
	public:
	int Re;
	int Im;
	Complex():Re(0),Im(0){};
	Complex(const int& tre,const int& tim):Re(tre),Im(tim){};
	Complex(const Complex&obj):Re(obj.Re),Im(obj.Im){};
	friend ostream& operator<<(ostream&,const Complex&);		
	friend istream& operator>>(istream&,const Complex&);
};

        ostream& operator<<(ostream&,const Complex&);	
	
	istream& operator>>(istream&,const Complex&);
#endif //_COMPLEX_H_
massiv.cpp:

Код: Выделить всё

#include "complex.h"

class TMas
{
        public:
        virtual void Print(void)=0;
        virtual void PrintElem(const int& id)=0;
        virtual void Input(void)=0;
        virtual void PrintCount(void)=0;
};

template <class TType> class Massiv: virtual public TMas
{
	public:
        Massiv():Head(NULL),Last(NULL),count(0){};
        Massiv(const Massiv& ob):
        Head(ob.Head),Last(ob.Last),count(ob.count){};
        ~Massiv(){};
        void Input(void);
        void PrintElem(const int& id);
        void PrintCount();
        void Print(void);
	int operator()(Massiv<TType>& obj){return obj.count;};
	TType operator[](const int& id);
        protected:
	struct TT{
                TType item;
                TT*next;
        };
	int count;
	TT *Head;
	TT *Last;
};

template <class TType>
void Massiv<TType>::Input(void)
{
	//..
}

template <class TType>
void Massiv<TType>::Print(void)
{
	//..
}

template <class TType>
TType Massiv<TType>: :o perator[](const int& id)
{
	//..
}

template <class TType>
void Massiv<TType>::PrintElem(const int& id)
{
	//..
}

template <class TType>
void Massiv<TType>::PrintCount(void)
{
	//..
}
massiv.h:

Код: Выделить всё

#ifndef _MASSIV_H_
#define _MASSIV_H_

using namespace std;

class TMas
{
        public:
        virtual void Print(void)=0;
        virtual void PrintElem(const int& id)=0;
        virtual void Input(void)=0;
        virtual void PrintCount(void)=0;
};

template <class TType> class Massiv: virtual public TMas
{
	public:
        Massiv():Head(NULL),Last(NULL),count(0){};
        Massiv(const Massiv& ob):
        Head(ob.Head),Last(ob.Last),count(ob.count){};
        ~Massiv(){};
        void Input(void);
        void PrintElem(const int& id);
        void PrintCount();
        void Print(void);
	int operator()(Massiv<TType>& obj){return obj.count;};
	TType operator[](const int& id);
        protected:
	struct TT{
                TType item;
                TT*next;
        };
	int count;
	TT *Head;
	TT *Last;
};

#endif // _MASSIV_H_
Юный Падаван

Аватара пользователя
Monopo
Сообщения: 119
Зарегистрирован: 06 дек 2007, 20:08
Откуда: Linux

Re: Makefile (LINUX)

Сообщение Monopo » 15 апр 2009, 17:41

main.cpp:

Код: Выделить всё

#include "complex.h"
#include "massiv.h"

using namespace std;

int main()
{
        TMas *TM;
        int out=0;
        char c,type;
        printf("Choose the type of Massiv:\n");
        printf("0 - int\n");
        printf("1 - double\n");
        printf("2 - float\n");
        printf("3 - complex\n");
        scanf("%c",&type);
        switch(type)
        {
                case '0': {TM=new Massiv <int> ; break;}
                case '1': {TM=new Massiv <double>; break;}
                case '2': {TM=new Massiv <float>; break;}
                case '3': {TM=new Massiv <Complex>; break;}
        };
        while(out!=1)
	{
		printf("\n\nEnter the command:\n");
		printf("a - Add the massiv\n");
		printf("e - A[i]\n");
                printf("x - int(A)\n");
                printf("p - Print\n");
		printf("c - EXIT\n");
                printf("\n>>\n");
		cin>>c;
                printf("\n");
		switch (c)
		{
			case 'a':{TM->Input();break;}
                        case 'e':
                        {
                                int id;
                                printf("Enter the index> ");
                                scanf("%d",&id);
                                TM->PrintElem(id);
                                break;
                        }
                        case 'p':{TM->Print();break;}
                        case 'x':{TM->PrintCount();break;}
                        case 'c':
                        {
                                out++;
                                break;
                        }
                        default:continue;
		}
	}
        return 0;
}

Компилятор выдает кучу ошибок, типа:

Код: Выделить всё

main.o :( .rodata._ZTV6MassivIiE[vtable for Massiv<int>+0x1c]): undefined reference to 'Massiv<int>::Print()'
И так для каждой функции в TMas и для каждого типа, в том числе и пользовательского. 16 ошибок. Подскажите, где накосячил??
Юный Падаван

Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Re: Makefile (LINUX)

Сообщение Romeo » 16 апр 2009, 13:11

Тебе нужно немного почитать о template'ах. Дело в том, что у тебя не сгенерированы тела методов для <int> по той причине, что в файле, в котором методы имплементированы нету инстанцирования шаблона. Перемести код методов класса в header файл и у тебя всё соберётся.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

Аватара пользователя
Monopo
Сообщения: 119
Зарегистрирован: 06 дек 2007, 20:08
Откуда: Linux

Re: Makefile (LINUX)

Сообщение Monopo » 20 апр 2009, 18:48

Romeo писал(а):...в котором методы имплементированы нету инстанцирования шаблона...
Да.. И вправду..
Romeo писал(а):Тебе нужно немного почитать о template'ах.
Спасибо))
Юный Падаван

Ответить