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

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

Войти
Регистрация
Восстановить пароль
 
VergilYamato
3 / 2 / 0
Регистрация: 22.08.2014
Сообщений: 64
#1

Не видно определений функций при раздельной компиляции - C++

15.07.2015, 00:15. Просмотров 258. Ответов 7
Метки нет (Все метки)

Описал класс и его наследника в заголовочном файле; самые громоздкие определения функций вынес в отдельные файлы, однако при компиляции/сборке эти определения не видно из файла с "main".
Здесь указан код для студии, однако при компиляции из консоли с помощью GCC - результата тоже ноль.
Студия ругается на "неразрешенный внешний символ" (подключение всех pdb-файлов, какие нашел в проекте, не помогло).
GCC прямо говорит, что не видит некоторые необходимые определения.
Все файлы абсолютно точно лежат в одной папке и подключены к проекту.
Предоставлю только один файл с определениями, потому что они абсолютно идентичны по своей структуре.

Заголовочный файл:
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
#pragma once //замена на стандартный способ через "#ifndef" ничего не дает
 
template<typename T>
class singleLinkedList
{
protected:
    struct list_elem
    {
        T el;
        list_elem *next;
    };
    list_elem *top;
    unsigned long size;
    void next_elem() { top = top->next; };
public:
    singleLinkedList() { top = NULL; size = 0; };
    bool is_empty() const { return top == NULL; };
    unsigned long list_size() { return size; };
    void show();                                        //выводим список
    virtual void add_elem(const T &elem);               //добавляем элемент
    virtual void del_elem();                            //удаляем элемент
    virtual void reverse();                             //разворачиваем список
    virtual ~singleLinkedList();
};
 
template<typename T>
class doubleLinkedList : public singleLinkedList<T>
{
private:
    struct list_elem
    {
        T el;
        list_elem *next;
        list_elem *prev;
    };
    list_elem *top;
    //unsigned long size;
    void next_elem() { top = top->next; };
    void prev_elem() { top = top->prev; };
public:
    doubleLinkedList() { top = NULL; size = 0; };
    bool is_empty() const { return top == NULL; };
    //unsigned long list_size() { return size; };
    void show() { singleLinkedList<T>::show(); };
    virtual void add_elem(const T &elem);               //добавляем элемент
    virtual void del_elem();                            //удаляем элемент
    virtual void reverse();                             //разворачиваем список
    virtual ~doubleLinkedList() { singleLinkedList<T>::~singleLinkedList(); };
};
Файл с определениями:
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
#include "stdafx.h"
#include <iostream>
#include "myList.h"
 
template<typename T>
void singleLinkedList<T>::add_elem(const T &elem)
{
    list_elem *new_el = new list_elem;
    new_el->el = elem;
    new_el->next = top;
    top = new_el;
};
template<typename T>
void singleLinkedList<T>::show()                        //выводим список
{
    list_elem *start = top;
    std::cout << "[";
    while (top != NULL)
    {
        std::cout << top->el << ", ";
        next_elem();
    }
    std::cout << "\b\b]";
    top = start;
};
template<typename T>
void singleLinkedList<T>::reverse()//разворот списка, колдуем с указателями
{
    list_elem *cur_elem = top;
    list_elem *next_elem = top->next;
    list_elem *prev_elem = NULL;
    cur_elem->next = prev_elem;
    while (next_elem != NULL)
    {
        prev_elem = cur_elem;
        cur_elem = next_elem;
        next_elem = cur_elem->next;
        cur_elem->next = prev_elem;
    }
    top = cur_elem;
};
template<typename T>
void singleLinkedList<T>::del_elem()
{
    switch (size)
    {
    case 0:
    {
        std::cout << "List is empty, imposable to delete something!";
        break;
    }
    case 1:
    {
        delete top;
        top = NULL;
        size--;
        break;
    }
    default:
    {
        list_elem *start = top->next;
        delete top;
        top = start;
        size--;
        break;
    }
    }
};
template<typename T>
singleLinkedList<T>::~singleLinkedList()
{
    list_elem *cur_el = top;
    while (top != NULL)
    {
        cur_el = top->next;
        delete top;
        top = cur_el;
        std::cout << "deleted\n";
    }
};
Файл с функцией "main":
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
#include "stdafx.h"
#include <iostream>
#include "myList.h"
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    singleLinkedList <int> l;
    if (l.is_empty()) for (int i = 1; i<5; i++) l.add_elem(i);
    l.show();
    std::cout << "\n";
    l.reverse();
    l.show();
    std::cout << "\n";
    l.del_elem();
    l.show();
    l.~singleLinkedList();
 
    doubleLinkedList <int> l1;
    if (l1.is_empty()) for (int i = 1; i<5; i++) l1.add_elem(i);
    l1.show();
    std::cout << "\n";
    l1.reverse();
    l1.show();
    std::cout << "\n";
    l1.del_elem();
    l1.show();
    l1.~doubleLinkedList();
    int n;
    std::cin >> n;
    return 0;
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2015, 00:15
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не видно определений функций при раздельной компиляции (C++):

При раздельной компиляции не работает перегрузка операторов ввода-вывода - C++
разделил программу и при компиляции компилятор ругается на объявление перегрузки операторов ввода вывода(на скриншотах видно что он...

Как правильно использовать заголовочные файлы при раздельной компиляции в MS Visual Studio? - C++
Если я использую функцию cout и cin в каждом модуле, мне нужно в каждом модуле прописывать : #include &lt;iostream&gt; using namespace std; ...

Реализация раздельной компиляции - C++
Здравствуйте! Я самоучка поэтому я... Я облазил кучу различных источников, но понял только принцип, по которому...

Порядок раздельной компиляции 3 файлов - C++
Что-то не пойму, объясните мне на пальцах, как откомпилировать три файла (1 заголовочный) вместе. Использую DEV-C++ . coordin.h: //...

Заголовочный файл или Механизм раздельной компиляции - C++
Здравствуйте в данный момент я изучаю C++. Среда разработки Visual Studio 2010 Столкнулся с понятием заголовочный файл и из чистого...

Как создать объект класса? ПРоблемма из-за раздельной компиляции - C++
Есть 4 файла engine.h - базовый класс engine.cpp - реализация методов базового класса car.h - класс поизводный от engine car.cpp -...

7
Croessmah
Эксперт CЭксперт С++
13514 / 7673 / 867
Регистрация: 27.09.2012
Сообщений: 18,896
Записей в блоге: 3
Завершенные тесты: 1
15.07.2015, 00:24 #2
1) Код шаблона должен быть доступен в месте инстанцирования, так что пишите определения после объявления шаблона (или отдельном файле, но потом его включайте в заголовок).

2) За такое:
C++
1
2
3
l.~doubleLinkedList();
//...
l1.~doubleLinkedList();
сразу в голову.
Кто научил вызывать деструктор автоматических объектов?
1
Max Dark
шКодер самоучка
1849 / 1649 / 603
Регистрация: 09.10.2013
Сообщений: 3,676
Записей в блоге: 6
Завершенные тесты: 2
15.07.2015, 00:25 #3
VergilYamato, шаблон должен быть описан полностью в заголовочном файле
1
Croessmah
Эксперт CЭксперт С++
13514 / 7673 / 867
Регистрация: 27.09.2012
Сообщений: 18,896
Записей в блоге: 3
Завершенные тесты: 1
15.07.2015, 00:27 #4
3)
C++
1
virtual ~doubleLinkedList() { singleLinkedList<T>::~singleLinkedList(); };
Вызов деструктора базового класса? Кто такое подсказал? Можете ему челюсть сломать в данном случае

Добавлено через 2 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
в голову.
Цитата Сообщение от Croessmah Посмотреть сообщение
челюсть сломать
чё т я злой сегодня но ведь справедливый
1
VergilYamato
3 / 2 / 0
Регистрация: 22.08.2014
Сообщений: 64
15.07.2015, 00:57  [ТС] #5
Цитата Сообщение от Croessmah Посмотреть сообщение
1) Код шаблона должен быть доступен в месте инстанцирования, так что пишите определения после объявления шаблона (или отдельном файле, но потом его включайте в заголовок).

2) За такое:
C++
1
2
3
l.~doubleLinkedList();
//...
l1.~doubleLinkedList();
сразу в голову.
Кто научил вызывать деструктор автоматических объектов?
1) То есть получается, что это возможно только для не шаблонного класса (видел как раз определение подобного класса с выносом части определений в отдельные файлы)?
2) Никто не учил, учу с++ самостоятельно по книжке Стивена Прата (этот способ не из книжки: сам придумал). Я что-то только щас подумал, что не обязательно вызывать деструктор для классов с динамическим выделением памяти. Ну а вообще здесь всё равно бы вызвать, чтобы проверить, как работает, нет ли багов.
3) Да, я уже понял, что не сработает, но пока менять код не стал. А задумка была в том, что деструкторы работают абсолютно идентично, жаль только, что я не учел, что list_elem переопределяется. По этой же причине и show() не будет работать, кстати.
0
Croessmah
Эксперт CЭксперт С++
13514 / 7673 / 867
Регистрация: 27.09.2012
Сообщений: 18,896
Записей в блоге: 3
Завершенные тесты: 1
15.07.2015, 01:04 #6
Цитата Сообщение от VergilYamato Посмотреть сообщение
нет ли багов.
такой вызов и есть баг! Деструкторы автоматических объектов вызываются автоматически при уничтожении объекта (выход из scope'а).
Цитата Сообщение от VergilYamato Посмотреть сообщение
Да, я уже понял, что не сработает, но пока менять код не стал.
деструктор базового класса вызовется автоматически.
0
VergilYamato
3 / 2 / 0
Регистрация: 22.08.2014
Сообщений: 64
15.07.2015, 01:29  [ТС] #7
Приму к сведению, прокомментируй 1), пожалуйста.
0
Croessmah
Эксперт CЭксперт С++
13514 / 7673 / 867
Регистрация: 27.09.2012
Сообщений: 18,896
Записей в блоге: 3
Завершенные тесты: 1
15.07.2015, 11:54 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
То есть получается, что это возможно только для не шаблонного класса
По сути - да. Была такая штука, как export, но в c++11 её отменили.
Можно, конечно же явно инстанцировать шаблон с определенными параметрами в какой-нибудь единице трансляции, но нужно ли Вам это?
0
15.07.2015, 11:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.07.2015, 11:54
Привет! Вот еще темы с ответами:

Нюансы раздельной компиляции: где и что лучше и правильнее размещать? - C++
Здравствуйте! Допустим, я хочу написать интерфейс класса в h-файле, а его реализацию в cpp-файле. Могу ли я в этом cpp-файле до...

Создать функцию которая возводит число в квадрат, использовать принцип раздельной компиляции - C++
Создать функцию которая возводит число в квадрат. Использовать принцип раздельной компиляции. Заранее спасибо!

Как на этапе компиляции создать необходимое количество шаблонных функций? - C++
Есть алгоритм, который использует функцию от одного аргумента. Этот же алгоритм должен использовать функцию, которая задаётся тем же одним...

Image - при компиляции картинки не видно - C++ Builder
загрузил картинку.jpg в компонент image при компиляции картинки не видно


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

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

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