01/10/2018, 01:06

Lỗi khi tách file template thành 2 file h và cpp trong c++

chào các bạn
mình có 1 template class , giờ mình muốn tách template này thành 2 file cpp, và file h,
nhưng khi tách phần định nghĩa ra khỏi file h, thì build bị lỗi, phải để phần định nghĩa trong file h nó mới chạy, phải làm ntn nhỉ
xin cam on

viết 03:15 ngày 01/10/2018

nhưng khi tách phần định nghĩa ra khỏi file h, thì build bị lỗi, phải để phần định nghĩa trong file h nó mới chạy, phải làm ntn nhỉ

để phần định nghĩa trong file h

Tao Không Ngu. viết 03:20 ngày 01/10/2018

Hi Nấm Lùnhell6w9rld.
File .h của bạn không để dịnh nghĩa thì để gì ?

chichi viết 03:20 ngày 01/10/2018

Mình nhớ cũng bị thế rồi, bạn thử đọc xem

stackoverflow.com
MainID

Why can templates only be implemented in the header file?

c++, templates, c++-faq
asked by MainID on 10:06AM - 30 Jan 09

HelloWorld viết 03:10 ngày 01/10/2018

nếu nhiều hàm thành phần , mà định nghĩa trong file h luôn thì nhìn rối lắm , nên mình tách nó ra file cpp, chưa định nghĩa, còn file h chỉ để prototype của hàm, như thế dễ bào trì và xem lại hơn

viết 03:11 ngày 01/10/2018

tách ra cũng được, nhưng ko phải là .h và .cpp mà là .h và .tpp. File định nghĩa các method sẽ ko được biên dịch nên ko đặt đuôi là .cpp hay .c**, đặt tên là .tpp có chữ ‘t’ là template.

example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <string>

template <typename Outputable>
std::string exampleToString(const Outputable& obj);

#include "example.tpp" //include file tpp tương ứng sau cùng

#define EXAMPLE_H

example.tpp

#include <sstream>

template <typename Outputable>
std::string exampleToString(const Outputable& obj)
{
    std::ostringstream oss;
    oss << obj;
    return oss.str();
}

để làm cho file .h dễ nhìn thôi chứ viết như vậy dài hơn.

HelloWorld viết 03:14 ngày 01/10/2018

đúng cái cần tìm, cam on ban
vì file h của mình khá nhiều hàm nên tách ra nó dễ nhìn và bảo trì hơn

HelloWorld viết 03:07 ngày 01/10/2018

bạn ơi,
mình tách file template ra h và tpp
nhưng bị lỗi
cái của mình là template class

file h

#ifndef _DOUBLE_LINKED_LIST_H_
#define _DOUBLE_LINKED_LIST_H_

#include "classroom.h"
#include <string>
#include <iostream>
using namespace std;

template <typename type>
struct node{
	type data;
	node *next, *previous;
};

template <typename T>
struct linked{
	node <T> *head, *tail;
};

template <class T>
class dll{
private:
	linked <T> list;
public:
	dll();
	node <T> *create_node(T );
	bool check_exist(string);
	void add_tail(T );
	void print_list();
	int count();
	void delete_list();
	void delete_element();
	// classroom
	void search_classroom();
	void update_classroom();
	void swap(node <T> *, node <T> *);
	void sort();
};
#include "double_linked_list.tpp"

#endif

file tpp

template <class T>
dll(){
	list.head = list.tail = NULL;
}

template <class T>
node <T> *create_node(T x){
	node <T> *temp = new node <T>;
	temp->data = x;
	temp->next = NULL;
	temp->previous = NULL;
	return temp;
}

template <class T>
bool check_exist(string id){
	node <T> *temp = list.head;
	while (temp != NULL){
		if (temp->data.id == id){
			return true;
			break;
		}
		temp = temp->next;
	}
	return false;
}

template <class T>
void add_tail(T x){
	if (check_exist(x.id)){
		cout << "Ma lop da ton tai" << endl;
		return;
	}
	node <T> *temp = create_node(x);
	if (list.head == NULL) list.head = list.tail = temp;
	else{
		temp->next = list.tail->next;
		list.tail->next = temp;
		temp->previous = list.tail;
		list.tail = temp;
	}
}

template <class T>
void print_list(){
	if (list.head == NULL)	return;
	node <T> *temp = list.head;
	while (temp != NULL){
		cout << temp->data;
		temp = temp->next;
	}
}

template <class T>
int count(){
	node <T> *temp = list.head;
	int count = 0;
	while (temp != NULL){
		count++;
		temp = temp->next;
	}
	return count;
}

template <class T>
void delete_list(){
	if (list.head == NULL) return;
	node <T> *temp;
	while (list.head != NULL){
		temp = list.head;
		list.head = list.head->next;
		delete temp;
	}
}

template <class T>
void delete_element(){
	cout << "Nhap id" << endl;
	string del;
	fflush(stdin);
	getline(cin, del);

	if (check_exist(del)) {
		node <T> *temp = list.head;
		while (temp != NULL){
			if (temp->data.id == del){
				if (temp == list.head){
					list.head = list.head->next;
					list.head->previous = NULL;
				}
				else if (temp == list.tail){
					list.tail = list.tail->previous;
					list.tail->next = NULL;
				}
				else{
					temp->previous->next = temp->next;
					temp->next->previous = temp->previous;
				}
				delete temp;
				break;
			}
			temp = temp->next;
		}
	}
	else cout << "Lop khong ton tai" << endl;
}




// classroom
template <class T>
void search_classroom(){
	// menu
	int option;
	cout << "1. Ma lop" << endl;
	cout << "2. Ten lop" << endl;
	cout << "3. Khoa" << endl;
	cout << "4. Nien Khoa" << endl;
	cin >> option;

	cout << "Nhap thong tin tim kiem" << endl;
	string search;
	fflush(stdin);
	getline(cin, search);

	node <T> *temp = list.head;
	while (temp != NULL){
		switch (option){
		case 1:  if (temp->data.id == search)	cout << temp->data;
			break;
		case 2:	 if (temp->data.tenlop == search)	cout << temp->data;
			break;
		case 3:	 if (temp->data.khoa == search)	cout << temp->data;
			break;
		case 4:	 if (temp->data.nienkhoa == search)	cout << temp->data;
			break;
		}
		temp = temp->next;
	}
}

template <class T>
void update_classroom(){
	cout << "Nhap id" << endl;
	string update;
	fflush(stdin);
	getline(cin, update);

	if (check_exist(update)) {
		node <T> *temp = list.head;
		while (temp != NULL){
			if (temp->data.id == update){
				// menu
				int option;
				cout << "1. Sua Ma Lop" << endl;
				cout << "2. Sua Ten Lop" << endl;
				cout << "3. Sua Khoa" << endl;
				cout << "4. Sua Nien Khoa" << endl;
				cin >> option;
				cout << "Nhap thong tin muon sua" << endl;
				string fix;
				fflush(stdin);
				getline(cin, fix);
				switch (option){
				case 1:	   // check ma lop o bang sinh vien
					break;
				case 2:		temp->data.tenlop = update;
					break;
				case 3:		temp->data.khoa = update;
					break;
				case 4:		temp->data.nienkhoa = update;
					break;
				}
				break;
			}
			temp = temp->next;
		}
	}
	else cout << "Lop khong ton tai" << endl;
}

template <class T>
void swap(node <T> *a, node <T> *b){
	string id = a->data.id;
	string tenlop = a->data.tenlop;
	string khoa = a->data.khoa;
	string nienkhoa = a->data.nienkhoa;

	a->data.id = b->data.id;
	a->data.tenlop = b->data.tenlop;
	a->data.khoa = b->data.khoa;
	a->data.nienkhoa = b->data.nienkhoa;

	b->data.id = id;
	b->data.tenlop = tenlop;
	b->data.khoa = khoa;
	b->data.nienkhoa = nienkhoa;
}

template <class T>
void sort(){
	int option;
	cout << "1. Sap xep theo ma lop" << endl;
	cout << "2.  Sap xep theo ten lop" << endl;
	cin >> option;


	for (node <T> *i = list.head; i->next != NULL; i = i->next){
		for (node <T> *j = i->next; j != NULL; j = j->next){
			switch (option){
			case 1: if (i->data.id > j->data.id)	swap(i, j);
				break;
			case 2: if (i->data.tenlop > j->data.tenlop)	swap(i, j);
				break;
			}
		}
	}
}
viết 03:19 ngày 01/10/2018

viết mấy cái định nghĩa cho method phải ghi đầy đủ ClassName::methodName() mà. Trong template thì ghi thêm <T> nữa.

vd

template <class T>
node<T>* dll<T>::create_node(T x)
{
    //...
}
Bài liên quan
0