Форум программистов, компьютерный форум CyberForum.ru

Проблема с линковкой - C++

Восстановить пароль Регистрация
 
Napalm256
2 / 2 / 0
Регистрация: 18.08.2011
Сообщений: 17
20.08.2011, 15:30     Проблема с линковкой #1
Пишу игру в Code::Blocks, использую glut.
Компилятор ошибок не выдаёт и обьектные файлы создаются, а вот линковщик ругается:


-------------- Clean: Debug in WormsCB ---------------

Cleaned "WormsCB - Debug"

-------------- Build: Debug in WormsCB ---------------

Compiling: List.cpp
Compiling: Vector.cpp
Compiling: main.cpp
Compiling: Core.cpp
Linking console executable: bin\Debug\WormsCB.exe
obj/Debug/Core.cpp.o: In function `Game':
D:/Documents/Programming/C/my/WormsCB/Core.cpp:33: undefined reference to `List<Particle, Game>::List()'
D:/Documents/Programming/C/my/WormsCB/Core.cpp:33: undefined reference to `List<Particle, Game>::List()'

obj/Debug/Core.cpp.o: In function `~Game':
D:/Documents/Programming/C/my/WormsCB/Core.cpp:41: undefined reference to `List<Particle, Game>::~List()'
D:/Documents/Programming/C/my/WormsCB/Core.cpp:41: undefined reference to `List<Particle, Game>::~List()'
obj/Debug/Core.cpp.o: D:/Documents/Programming/C/my/WormsCB/Core.cpp:170: undefined reference to `List<Particle, Game>:: push_front(Particle)'
obj/Debug/Core.cpp.o: D:/Documents/Programming/C/my/WormsCB/Core.cpp:176: undefined reference to `List<Particle, Game>:: push_front(Particle)'
obj/Debug/Core.cpp.o: D:/Documents/Programming/C/my/WormsCB/Core.cpp:181: undefined reference to `List<Particle, Game>:: push_front(Particle)'
obj/Debug/Core.cpp.o: D:/Documents/Programming/C/my/WormsCB/Core.cpp:216: undefined reference to `List<Particle, Game>:: forIn(void (Game::*)(Particle&))'

collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 1 seconds)
8 errors, 0 warnings


Незнаю поможет ли чем то но вот что в Core.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
#include <windows.h>
 
#include <GL/glut.h>
 
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <iostream>
#include <fstream>
 
using namespace std;
 
// MY_OBJECTS
 
#include "List.h"
#include "Vector.h"
 
// END_MY_OBJECTS
 
class Game
{
public:
    List<Particle,Game> particles;
...
};
...
List - это шаблон списка
Vector - абстрактный класс с прегружеными операторами.
Их писал отдельно от проекта и тестировал там проблем нет...
Подскажите что это за болезнь такая О_о.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.08.2011, 15:30     Проблема с линковкой
Посмотрите здесь:

проблемы с линковкой C++
C++ Дорогие, помогите с линковкой libeay32.lib
Проблема в стэке C++
Проблема C++
Проблема с линковкой C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
20.08.2011, 16:03     Проблема с линковкой #2
в List.h должно быть не только объявление класса, но и полное определение его методов
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
20.08.2011, 16:31     Проблема с линковкой #3
Цитата Сообщение от Napalm256 Посмотреть сообщение
но вот что в Core.h
Не используй using namespace в хэдэрах. НИ-КО-ГДА.
Napalm256
2 / 2 / 0
Регистрация: 18.08.2011
Сообщений: 17
20.08.2011, 16:35  [ТС]     Проблема с линковкой #4
В List.cpp и в остальных есть определение всех функций которые декларированы в хедере

Deviaphan, поменял но ничего не изменилось те же самые ошибки линковки =(
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
20.08.2011, 16:39     Проблема с линковкой #5
Napalm256, шаблоны нельзя разделять, они должны быть все в .h
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
20.08.2011, 16:40     Проблема с линковкой #6
Цитата Сообщение от Napalm256 Посмотреть сообщение
В List.cpp
Реализация шаблона должна быть в хэдэре.
Napalm256
2 / 2 / 0
Регистрация: 18.08.2011
Сообщений: 17
20.08.2011, 17:07  [ТС]     Проблема с линковкой #7
Теперь изменения пошли и появились новые странные ошибки типа:
...\List.h|11|instantiated from 'void List<Type, Object>:: push_front(Type) [with Type = Particle, Object = Game]'
...\List.h|11|error: no matching function for call to 'Particle::Particle()'|
|

Ведь можно вызывать функцию которая принимает класс как аргумент где аргументом есть конструктор??
C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
    A();
};
class B
{
   someFun(A&);
}
...
B b1;
b1.somefun(A());
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
20.08.2011, 17:09     Проблема с линковкой #8
у класс A приватный конструктор
LosAngeles
Заблокирован
20.08.2011, 17:38     Проблема с линковкой #9
можно определения шаблонов хранить в срр и подключать его в конце хидера с объявлениями, но при этом не подключать срр в проект. Это на случай, если религия не позволяет всё в хидере писать, а так то это бесполезно делать

Добавлено через 4 минуты
или скачать какое нибудь подделие от edison group design и наслаждаться раздельной компиляцией
http://www.edg.com/index.php?location=c_lang
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
20.08.2011, 18:58     Проблема с линковкой #10
Цитата Сообщение от LosAngeles Посмотреть сообщение
можно определения шаблонов хранить в срр и подключать его в конце хидера с объявлениями
Расширение файла ни на что не влияет. Можешь хоть "source.my_extension" написать, но это всё равно хэдэр будет.
LosAngeles
Заблокирован
20.08.2011, 19:09     Проблема с линковкой #11
Цитата Сообщение от Deviaphan Посмотреть сообщение
Расширение файла ни на что не влияет. Можешь хоть "source.my_extension" написать, но это всё равно хэдэр будет.
спасибо кэп
Napalm256
2 / 2 / 0
Регистрация: 18.08.2011
Сообщений: 17
20.08.2011, 19:31  [ТС]     Проблема с линковкой #12
Блин я уже запарился: если что то меняю - то уже что то новое не нравиться компилятору, ошибки гуглил, но у всех разные ситуации... Вот исходник шаблона списка:
Список ошибок


List.h||In constructor 'List<Particle, Game>::ls::ls()':|
List.h|11|instantiated from 'void List<Type, Object>::push_front(Type) [with Type = Particle, Object = Game]'|
Core.cpp|172|instantiated from here|
Core.cpp 172 стока
C++
1
particles.push_front(Particle(x, y, rand()%500 - 250, rand()%200, 0.0, 200.0));
List.h|11|error: no matching function for call to 'Particle::Particle()'|
Core.cpp|9|note: candidates are: Particle::Particle(float, float, float, float, float, float)|
Core.h|33|note: Particle::Particle(const Particle&)|
List.h||In member function 'void List<Type, Object>::push_front(Type) [with Type = Particle, Object = Game]':|
List.h|97|note: synthesized method 'List<Particle, Game>::ls::ls()' first required here |
List.h||In member function 'void List<Type, Object>::forIn(void (Object::*)(Type&)) [with Type = Particle, Object = Game]':|
Core.cpp|218|instantiated from here|
List.h|206|error: must use '.*' or '->*' to call pointer-to-member function in 'fun (...)', e.g. '(... ->* fun) (...)'|

||=== Build finished: 2 errors, 0 warnings ===|


List.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
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
 
template <class Type, class Object> class List
{
public:
    struct ls    // реализация динамического списка
    {
        Type data;
        ls *next; // указатель на следующий елемент списка
    };
    ls *p1;
    Type *error;
    static Type err;
    typedef void (Object::* pListFunc)(Type&);
    pListFunc pf;
    List();
    ~List();
 
    void push_back(Type); // поместить в конец
    void pop_back();  // изъять с конца
    void push_front(Type); // аналогично
    void pop_front();
    void remove(long); //удалить элемент по индексу
    void insert(Type,long); // тоже только наоборот
    long size(); // узнать размер списка
    void forIn(void (Object::*)(Type&)); // реализация for переменная in список
    void forIn(void (*)(Type&));
 
    Type &operator[](const long); // обращение по индексу к єлементам
};
 
//template <class Type, class Object> Type *List<Type,Object>::err = NULL;
 
 
// LIST_INPLAMENTATION
 
template <class Type, class Object> List<Type, Object>::List()
{
    error = &err;
    p1 = NULL;
}
 
template <class Type, class Object> List<Type,Object>::~List()
{
    ls *ptmp = p1,*pdel;
    while(ptmp)
    {
        pdel = ptmp;
        ptmp = ptmp->next;
        delete pdel;
    }
    delete ptmp;
}
 
template <class Type, class Object> void List<Type, Object>::push_back(Type data)
{
    if(!p1)
    {
        p1 = new ls;
        p1->data = data;
        p1->next = NULL;
        //cout << "push back first element " << p1->data << "\n";
    } else
    {
        ls *ptmp = p1;
        while(ptmp->next)
            ptmp = ptmp->next;
        ptmp->next = new ls;
        ptmp = ptmp->next;
        ptmp->data = data;
        ptmp->next = NULL;
        //cout << "push back " << ptmp->data << "\n";
    }
}
 
template <class Type, class Object> void List<Type, Object>::pop_back()
{
    ls *ptmp = p1, *ptmpLast = p1;
    while(ptmp->next)
    {
        ptmpLast = ptmp;
        ptmp = ptmp->next;
    }
    ptmpLast->next = NULL;
    delete ptmp;
}
 
template <class Type, class Object> void List<Type, Object>::push_front(Type data)
{
    if(!p1)
    {
        p1 = new ls;
        p1->data = data;
        p1->next = NULL;
        return;
    }
    ls *ptmp = new ls;
    ptmp->next = p1;
    ptmp->data = data;
    p1 = ptmp;
}
 
template <class Type, class Object> void List<Type, Object>::pop_front()
{
    if(!p1)
        return;
    ls *ptmp = p1->next;
    delete p1;
    p1 = ptmp;
}
 
template <class Type, class Object> void List<Type, Object>::remove(long i)
{
    if(!p1)
        return;
 
    ls *ptmp = p1,*plast = p1;
    long j = 0;
 
    while(ptmp)
    {
        if(j==i && ptmp)
        {
            plast->next = ptmp->next;
            delete ptmp;
            return;
        }
        j++;
        plast = ptmp;
        ptmp = ptmp->next;
    }
    //cout << "*** ERROR: out of memory List[" << i << "]\n";
}
 
template <class Type, class Object> void List<Type, Object>::insert(Type data, long i)
{
    if(!p1)
    {
        p1 = new ls;
        p1->data = data;
        p1->next = NULL;
        return;
    }
 
    ls *ptmp = p1;
    long j = 0;
 
    while(ptmp)
    {
        if(j==i && ptmp)
        {
            ls *pin = ptmp->next;
            ptmp->next = new ls;
            ptmp = ptmp->next;
            ptmp->data = data;
            ptmp->next = pin;
            return;
        }
        j++;
        ptmp = ptmp->next;
    }
    //cout << "*** ERROR: out of memory List[" << i << "]\n";
}
 
template <class Type, class Object> long List<Type, Object>::size()
{
    ls *ptmp = p1;
    long i = 0;
    while(ptmp)
    {
        ptmp = ptmp->next;
        i++;
    }
    return i;
}
 
template <class Type, class Object> Type &List<Type, Object>::operator[](const long i)
{
    ls *ptmp = p1;
    long j = 0;
 
    while(ptmp)
    {
        if(j==i && ptmp)
        {
            //Type *p = &ptmp->data;
            return ptmp->data;
        }
        j++;
        ptmp = ptmp->next;
    }
    //cout << "*** ERROR: out of memory List[" << i << "]\n";
    return &err;
}
 
template <class Type, class Object> void List<Type, Object>::forIn(void (Object::*fun)(Type &data))
{
    ls *ptmp = p1;
    while(ptmp)
    {
        fun(ptmp->data);
        ptmp = ptmp->next;
    }
}
 
template <class Type, class Object> void List<Type, Object>::forIn(void (*fun)(Type &data))
{
    ls *ptmp = p1;
    while(ptmp)
    {
        fun(ptmp->data);
        ptmp = ptmp->next;
    }
}
 
// END_OF_LIST_INPLAMENTATION
 
 
#endif // LIST_H_INCLUDED


Сразу скажу для тех кто считает что это ересь и можно вместо списка использовать вектор: надо было реализовать функцию на подобии for <переменная> in <список> потому что идёт работа с частицами, а их очень много (больше тысячи) тесть я избегаю повторного прохода по списку при индексному доступу, а так говорите если что ...
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
20.08.2011, 19:46     Проблема с линковкой #13
Цитата Сообщение от Napalm256 Посмотреть сообщение
надо было реализовать функцию на подобии for <переменная> in <список>
Вот как раз для таких ситуёвин вектор идеальный контейнер.
Napalm256
2 / 2 / 0
Регистрация: 18.08.2011
Сообщений: 17
20.08.2011, 20:33  [ТС]     Проблема с линковкой #14
Кажется мне что вы не поняли в чём соль, или я плохо искал в векторе, но я не нашел как сделать что то с элементами списка не вызывая тысячу раз обращение по индексу, а это динамический список и чтобы дойти до нужного элемента по индексу нужно проходить весь список по порядку по несколько раз, а в моём примере как раз и реализован этот метод. Будет очень неприятно если игра на пару мегабайт будет жутко тормозить из за плохой оптимизации.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
20.08.2011, 20:37     Проблема с линковкой #15
что значит не обращаясь по индексу, так чтоли?
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <vector>
#include <iostream>
 
int main()
{
  std::vector<int> v;
  v.push_back( 10 );
  v.push_back( 20 );
  int& ref = v[1];
  ref = 100;
  std::cout << v[1] << std::endl;     
}
Napalm256
2 / 2 / 0
Регистрация: 18.08.2011
Сообщений: 17
20.08.2011, 21:07  [ТС]     Проблема с линковкой #16
alex_x_x нет. Вы просто запоминаете последнее значение.

C++
1
2
3
4
5
6
7
8
void Game::particleConrtol(Particle &p)
{
    p.Move(deltaTime);
    particleCollision(p);
    particleDraw(p);
}
 
particles.forIn(&Game::particleConrtol); // эта функция описана в посте выше
я когда то сделал тест на скорость сортировки python vs c++ (гдето на ютубе было) так там разница во времени колоссальная. А причина, полагаю, в том что питон при вызове a[i] сначала проходит по всему массиву и когда дойдёт до нужного возвращает то что хранится там, и при вызове a[i+1] тоже с начала считать будет.

Добавлено через 15 минут
Вот, кому интересно где сила плюсов
Python: 17сек
C++: 0.2cек
Python

Python
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
import random
 
NUM_COUNT = 1000000
 
def genMassToFile():
    #r = range(NUM_COUNT)
    #ext.randrange(r)
    f = file('mass.txt','w')
    for i in range(NUM_COUNT):
        f.write(str(random.randrange(0,100000)))
        f.write('\n')
    f.close
 
def sortMassFromFile():
    f = file('mass.txt','r')
    f2 = file('mass2.txt','w')
    r = []
    for i in range(NUM_COUNT):
        s = f.read()
        tmp = s.split()
        for j in range(len(tmp)):
            r.append(int(tmp[j]))
    r = sorted(r)
    for i in range(NUM_COUNT):
        f2.write(str(r[i]))
        f2.write('\n')
    f.close()
    f2.close()
 
genMassToFile()
sortMassFromFile()


C++

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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define MASS_SIZE 1000
#define MASS_SIZE_2 MASS_SIZE>>2
 
void generate()
{
    FILE *f = fopen("mass.txt","wt");
    srand(time(0));
    int mass[MASS_SIZE],temp;
    unsigned int r;
 
    for(unsigned int i = 0;i<MASS_SIZE;i++)
    {
        r = rand() % MASS_SIZE - MASS_SIZE_2;
        temp = mass[i];
        mass[i] = mass[r];
        mass[r] = temp;
    }
    for(unsigned int i = 0;i<MASS_SIZE;i++)
    {
        fprintf(f,"%d\n",mass[i]);
    }
 
    fclose(f);
}
 
int *readFileToMass(int *mass)
{
    FILE *f;
    if(!(f=fopen("mass.txt","rt")))
    {
        printf("no such file\n");
        exit(0);
    }
 
    unsigned int i = 0;
    while(true)
    {
        fscanf(f,"%d\n",&mass[i]);
        if(feof(f)) break;
    }
    fclose(f);
    return mass;
}
 
void writeMassToFile(int *mass)
{
    FILE *f;
    f = fopen("mass2.txt","wt");
    for(unsigned int i = 0;i<MASS_SIZE;i++)
    {
        fprintf(f,"%d\n",mass[i]);
    }
    fclose(f);
}
 
void sort(int *mass)
{
    int temp;
    unsigned int i,j;
    for(i = 1;i<MASS_SIZE;i++)
    {
        j = i;
        
        while((mass[j] < mass[j-1]) && j>0)
        {
            temp = mass[j];
            mass[j] = mass[j-1];
            mass[--j] = temp;
        }
    }
}
 
int main()
{
    int mass[MASS_SIZE];
    
    generate();
    readFileToMass(mass);
    sort(mass);
    writeMassToFile(mass);
    return 0;
}
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
20.08.2011, 21:11     Проблема с линковкой #17
Цитата Сообщение от Napalm256 Посмотреть сообщение
alex_x_x нет. Вы просто запоминаете последнее значение.
вообще-то нет, запоминается ссылка, и значение присваивается элементу внутри массива
вы бы попробовали чтоли

и обрисуйте чтоли задачу, а то я устал гадать, что там за индексы и какойто непонятный обход
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2011, 21:19     Проблема с линковкой
Еще ссылки по теме:

Проблема с do-while C++
C++ В чём разница между динамической и статической линковкой библиотеки?

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

Или воспользуйтесь поиском по форуму:
LosAngeles
Заблокирован
20.08.2011, 21:19     Проблема с линковкой #18
Цитата Сообщение от Napalm256 Посмотреть сообщение
А причина, полагаю, в том что питон при вызове a[i] сначала проходит по всему массиву и когда дойдёт до нужного возвращает то что хранится там, и при вызове a[i+1] тоже с начала считать будет.
по этой причине в std::list нет оператора[], потому что сложность линейная, а вектор как обычный массив ведёт в этом случае сложность константная всего одна операция
Yandex
Объявления
20.08.2011, 21:19     Проблема с линковкой
Ответ Создать тему
Опции темы

Текущее время: 08:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru