Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Ryder95
9 / 9 / 4
Регистрация: 24.10.2013
Сообщений: 216
#1

Ошибка "undefined reference to" - C++

26.09.2014, 02:12. Просмотров 7463. Ответов 34
Метки нет (Все метки)

Здравствуйте. Пишу набор функций, состоящих из двух файлов: fileio.h и fileio.cpp
Попытался подключить это к main.cpp, и использовать makefile, вылезла ошибка:
Код
main.cpp:(.text+0x2a): undefined reference to `int* finput<int>(int*, unsigned long*, char*, bool)'
Вот как выглядит заголовочный файл:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <fstream>
using namespace std;
 
template <typename type>
type* finput(type*,unsigned long*,char*,bool f=0);
template <typename type>
type* finput(type*,unsigned long,char*,bool f=0);
 
template <typename type>
unsigned char foutput(type*,unsigned long,char*,bool f=0);
unsigned char foutput(char*,unsigned long,char*,bool f=0);
И файл с функциями:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "fileio.h"
 
template <typename type>
type* finput(type* array,unsigned long* count,char* path,bool f)
//Функция чтения неизвестного количества однотипных данных из файлов
{
    if (f) //Если двоичный файл
    {
        ifstream file(path,ios::binary|ios::ate);//Открытие бинарного файла с конца
        if (file) //Если файл открылся
        {
            if (file.tellg()%sizeof(type)) return (type*)1; //Файл повреждён
            *count=file.tellg()/sizeof(type);//Определение количества элементов
            array=new type[*count];//Выделение памяти под элементы
            file.clear();
            file.seekg(0);//Перевод маркера в начало файла
            file.read((char*)array,*count*sizeof(type));//Чтение
            return array;
        }
        else return (type*)0; //Если файл не открылся
    }
    else //Если файл текстовый
    {
        ifstream file(path);//Открытие файла
        if (file)//Если файл открылся
        {
            *count=0;
            for (register type i;!file.eof();)
                if (file>>i) (*count)++;
                else
                    if (!file.eof()) return (type*)1;//Файл повреждён
            file.clear();
            file.seekg(0);
            array=new type[*count];
            for(register unsigned long i=0;i<*count;i++)
                file>>array[i];
            return array;
        }
        else return (type*)0;//Файл не открылся
    };
};
template <typename type>
type* finput(type* array,unsigned long count,char* path,bool f)
//Функция для чтения определённого количество однотипных данных из файлов
{
    if (f)//Если бинарный файл
    {
        ifstream file(path,ios::binary|ios::ate);
        if (file)//Если файл открылся
        {
            if (file.tellg()<count*sizeof(type)) return (type*)1;//Повреждённый файл
            file.clear();
            file.seekg(0);
            array=new type[count];
            file.read((char*)array,count*sizeof(type));//Чтение
            return array;
        }
        else return 0;//Если файл не открылся
    }
    else//Если текстовый файл
    {
        ifstream file(path);
        if (file)//Если файл открылся
        {
            array=new type[count];
            for(register unsigned long i=0;i<count;i++)
                if (!(file>>array[i]))//Файл повреждён
                {
                    delete []array;
                    return (type*)1;
                } ;
            return array;
        }
        else return (type*)0;//Если файл не открылся
    };
};
 
template <typename type>
unsigned char foutput(type* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(type)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i]<<' ';
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
unsigned char foutput(char* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных типа char
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(char)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i];
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
Makefile написал вручную, выглядит так:
Код
all: main

main: main.o fileio.o
	g++ main.o fileio.o -o main

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

fileio.o: fileio.h fileio.cpp
	g++ -c fileio.h fileio.cpp
В чём моя ошибка?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.09.2014, 02:12
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Ошибка "undefined reference to" (C++):

Работа с шаблонами и ошибка "Undefined reference" - C++
только приступил к изучению шаблонов и сразу куча вопросов и проблем прошу объяснить мне на пальцах почему не работает matrix.h ...

ошибка "undefined reference" - C++
Изучаю С++ по книге Дейтелов. Работаю в Code Blocks Вот запнулся. Изучаю рекурсию на примере числа Фибоначчи. Пример списан с книги, но у...

"undefined reference" при инклюде внешних классов/библиотек - C++
Используется: Eclipse CDT, MinGW Немного сырцов: #ifndef STACK_H_ #define STACK_H_ template&lt;class T&gt; class...

Не собирается проект с шаблонным классом: "undefined reference" - C++
Подскажите пожалуйста, не собирается проект. Пишет &quot;undefined reference to Unit::Set()&quot; и такое же про Unit::Get(); Unit.h #ifndef...

Работа с загаловочными файлами ("Undefined reference to") - C++
Доброго времени суток. Не пойму почему компилятор Code Blocks выдаёт мне следующий ERROR: Undefined reference to 'summa(int, int) ...

Undefined reference to "MyClass::DEFAULT_CHANNEL_NUMBER" - C++
доброго времени суток, допустим есть класс class MyClass { static const unsigned int DEFAULT_CHANNEL_NUMBER = 0; std::map&lt;unsigned,...

34
MakItSim
17 / 17 / 9
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 02:19 #2
Шаблоны определяй прямо в .h файле. Иначе, какая функция, как ты думаешь, у тебя реализована в fileio.o? При компиляции fileio.o компилятор ничего о твоем main не знает, и каким параметром инстанцировать шаблон, соответственно, тоже.
0
Ryder95
9 / 9 / 4
Регистрация: 24.10.2013
Сообщений: 216
26.09.2014, 09:39  [ТС] #3
То есть мне нужно все функции, точнее их инструкции, сразу перенести в fileio.h? Дело в том, что у меня задача именно использовать два файла: fileio.h и fileio.cpp, где в .h будут только экземпляры, а в fileio.cpp уже будут только инструкции, причём в файле fileio.h не должно быть инклюда на fileio.cpp, то есть это нужно сделать с помощью makefile. Я два дня пытался понять, как в файл .o он соединяет два fileio.h и fileio.cpp, но не понял. Теперь вот он выводит такую ошибку. И если main.cpp ничего не знает о функции, вызываемой внутри, то как ему об этом сообщить?
0
MakItSim
17 / 17 / 9
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 09:56 #4
Цитата Сообщение от Ryder95 Посмотреть сообщение
То есть мне нужно все функции, точнее их инструкции, сразу перенести в fileio.h?
Не функции, а шаблоны. Функции может оставит на месте.
Цитата Сообщение от Ryder95 Посмотреть сообщение
Дело в том, что у меня задача именно использовать два файла: fileio.h и fileio.cpp, где в .h будут только экземпляры, а в fileio.cpp уже будут только инструкции
Тогда пиши обычными функциями.
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 10:34 #5
Сообщение undefined reference to значит, что компилятор функцию знает, но линкер не догадывается, где она валяется. Для исправления надо включить в проект файлы с телами всех используемых версий всех функций. Если функции библиотечные, то это делается подключением lib файлов, или со статическими библиотеками, или с библиотеками импорта в зависимости от того, валяются ли функции в lib, или в dll. В том числе это относится к своим библиотекам. В остальных случаях добавить в проект файлы с исходниками тел функций. Где именно они будут валяться - дело 128-е, но пихать их в голову - плохая идея.
0
MakItSim
17 / 17 / 9
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 10:47 #6
Цитата Сообщение от taras atavin Посмотреть сообщение
но пихать их в голову - плохая идея.
Как раз, шаблоны именно там и должны быть. Уже была тема, я помню:
Шаблоны. Ошибка компиляции: "Не удается сопоставить определение функции существующему объявлению"
Цитата Сообщение от taras atavin Посмотреть сообщение
Если функции библиотечные, то это делается подключением lib файлов, или со статическими библиотеками, или с библиотеками импорта в зависимости от того, валяются ли функции в lib, или в dll
Если ты явно не заиспользуешь функцию с нужными тебе типами, никаких функций из шаблона нигде не появится.
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 10:49 #7
Цитата Сообщение от MakItSim Посмотреть сообщение
Если ты явно не заиспользуешь функцию с нужными тебе типами, никаких функций из шаблона нигде не появится.
Ну как бы по факту линкер ругнулся, значит использованы.
0
MakItSim
17 / 17 / 9
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 10:53 #8
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну как бы по факту линкер ругнулся, значит использованы.
Они использованы в main. А это другая единица трансляции. До мэйна, компилируется fileio.o - другая единица. В ней функции не использованы, поэтому шаблоны "не превратились" в функции. А main идет уже после и использует существующий объектник, в котором нет функций.
0
alsav22
5437 / 4832 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.09.2014, 12:34 #9
fileio.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unsigned char foutput(char*,unsigned long,char*,bool f=0);
 
template <typename type>
type* finput(type* array,unsigned long* count,char* path,bool f)
//Функция чтения неизвестного количества однотипных данных из файлов
{
    if (f) //Если двоичный файл
    {
        ifstream file(path,ios::binary|ios::ate);//Открытие бинарного файла с конца
        if (file) //Если файл открылся
        {
            if (file.tellg()%sizeof(type)) return (type*)1; //Файл повреждён
            *count=file.tellg()/sizeof(type);//Определение количества элементов
            array=new type[*count];//Выделение памяти под элементы
            file.clear();
            file.seekg(0);//Перевод маркера в начало файла
            file.read((char*)array,*count*sizeof(type));//Чтение
            return array;
        }
        else return (type*)0; //Если файл не открылся
    }
    else //Если файл текстовый
    {
        ifstream file(path);//Открытие файла
        if (file)//Если файл открылся
        {
            *count=0;
            for (register type i;!file.eof();)
                if (file>>i) (*count)++;
                else
                    if (!file.eof()) return (type*)1;//Файл повреждён
            file.clear();
            file.seekg(0);
            array=new type[*count];
            for(register unsigned long i=0;i<*count;i++)
                file>>array[i];
            return array;
        }
        else return (type*)0;//Файл не открылся
    };
};
template <typename type>
type* finput(type* array,unsigned long count,char* path,bool f)
//Функция для чтения определённого количество однотипных данных из файлов
{
    if (f)//Если бинарный файл
    {
        ifstream file(path,ios::binary|ios::ate);
        if (file)//Если файл открылся
        {
            if (file.tellg()<count*sizeof(type)) return (type*)1;//Повреждённый файл
            file.clear();
            file.seekg(0);
            array=new type[count];
            file.read((char*)array,count*sizeof(type));//Чтение
            return array;
        }
        else return 0;//Если файл не открылся
    }
    else//Если текстовый файл
    {
        ifstream file(path);
        if (file)//Если файл открылся
        {
            array=new type[count];
            for(register unsigned long i=0;i<count;i++)
                if (!(file>>array[i]))//Файл повреждён
                {
                    delete []array;
                    return (type*)1;
                } ;
            return array;
        }
        else return (type*)0;//Если файл не открылся
    };
};
 
template <typename type>
unsigned char foutput(type* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(type)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i]<<' ';
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
fileio.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <fstream>
using namespace std;
 
unsigned char foutput(char* array,unsigned long count,char* path,bool f)
//Функция для записи в файл данных типа char
{
    if (f) //Для бинарного файла
    {
        ofstream file(path,ios::binary);
        if (file)
        {
            file.write((char*)array,sizeof(char)*count);
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    }
    else //Для текстового файла
    {
        ofstream file(path);
        if (file)
        {
            for(register unsigned i=0;i<count;i++)
                file<<array[i];
            return 1;//Файл открылся и записан удачно
        }
        else return 0;//Файл не открылся
    };
};
main
C++
1
2
3
4
5
6
7
8
9
#include <fstream>
#include "fileio.h"
using namespace std;
 
 
int main()
{
    ....
}
0
Ryder95
9 / 9 / 4
Регистрация: 24.10.2013
Сообщений: 216
26.09.2014, 17:23  [ТС] #10
То есть, как я понял, к шаблонам экземпляр сделать невозможно, верно?
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 17:27 #11
А что вообще такое экземпляр к шаблону? Экземпляры бывают у классов, а шаблоны сами по себе.
0
MakItSim
17 / 17 / 9
Регистрация: 23.09.2014
Сообщений: 117
26.09.2014, 17:29 #12
Цитата Сообщение от Ryder95 Посмотреть сообщение
То есть, как я понял, к шаблонам экземпляр сделать невозможно
Экземпляр чего?
0
taras atavin
3888 / 1762 / 92
Регистрация: 24.11.2009
Сообщений: 27,565
26.09.2014, 17:43 #13
Конечно можно. Экземпляры бывают у любых не абстрактных классов, шаблон абстрактного класса не имеет смысла.
0
Ryder95
9 / 9 / 4
Регистрация: 24.10.2013
Сообщений: 216
26.09.2014, 19:01  [ТС] #14
Тогда я совсем ничего не понимаю(
0
alsav22
5437 / 4832 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.09.2014, 19:27 #15
Цитата Сообщение от Ryder95 Посмотреть сообщение
То есть, как я понял, к шаблонам экземпляр сделать невозможно, верно?
Экземпляр шаблона создаётся, в частности, тогда, когда компилятор встречает вызов шаблонной функции. Это заставляет его сгенерировать экземпляр функции, используя определённый тип данных. Поэтому, в месте вызова шаблонной функции, для компилятора должна быть доступна реализация шаблона. Сам шаблон не является определением функции. Определением является экземпляр функции, сгенерированный по шаблону (экземпляр шаблона).
0
26.09.2014, 19:27
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.09.2014, 19:27
Привет! Вот еще темы с ответами:

Исправить ошибку "undefined reference" - C++
Компилирую в Ubuntu 14.04 Code::Block Есть 3 файла. klass.h initial.cpp main.cpp klass.h #include &lt;iostream&gt; #include...

Code::Blocks. "undefined reference to" - C++
Доброго времени суток! Это опять я :) Столкнулся со следующей проблемой. Есть 5 файлов: main.cpp --- здесь функция int...

G++ undefined reference to `Direct3DCreate9@4'" - C++
в визуале норм компилил.. даже без путей... а G++ отказывается ! выдаёт undefined reference to `Direct3DCreate9@4'&quot; . В чем проблема? //...

Странная ошибка: [Linker error] undefined reference to `__dyn_tls_init_callback' [Linker error] undefined reference to ld returned 1 exit status - C++
Здравствуйте. Вот недавно начал изучать книгу &quot;С++ для чайников&quot; Стефан Р. Девис 4-е издание. И напоролся на кучу ошибок) Но смог все...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru