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

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

Восстановить пароль Регистрация
 
VergilYamato
0 / 0 / 0
Регистрация: 22.08.2014
Сообщений: 38
15.07.2015, 00:15     Не видно определений функций при раздельной компиляции #1
Описал класс и его наследника в заголовочном файле; самые громоздкие определения функций вынес в отдельные файлы, однако при компиляции/сборке эти определения не видно из файла с "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;
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2015, 00:15     Не видно определений функций при раздельной компиляции
Посмотрите здесь:

C++ Ошибка при компиляции
Warning при компиляции при чтении из msado15.dll C++
Заголовочный файл или Механизм раздельной компиляции C++
Ошибка при компиляции C++
C++ Реализация раздельной компиляции
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,829
Записей в блоге: 2
Завершенные тесты: 1
15.07.2015, 00:24     Не видно определений функций при раздельной компиляции #2
1) Код шаблона должен быть доступен в месте инстанцирования, так что пишите определения после объявления шаблона (или отдельном файле, но потом его включайте в заголовок).

2) За такое:
C++
1
2
3
l.~doubleLinkedList();
//...
l1.~doubleLinkedList();
сразу в голову.
Кто научил вызывать деструктор автоматических объектов?
Max Dark
В поиске работы
 Аватар для Max Dark
1546 / 1399 / 501
Регистрация: 09.10.2013
Сообщений: 3,185
Записей в блоге: 8
Завершенные тесты: 2
15.07.2015, 00:25     Не видно определений функций при раздельной компиляции #3
VergilYamato, шаблон должен быть описан полностью в заголовочном файле
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,829
Записей в блоге: 2
Завершенные тесты: 1
15.07.2015, 00:27     Не видно определений функций при раздельной компиляции #4
3)
C++
1
virtual ~doubleLinkedList() { singleLinkedList<T>::~singleLinkedList(); };
Вызов деструктора базового класса? Кто такое подсказал? Можете ему челюсть сломать в данном случае

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

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

Как создать объект класса? ПРоблемма из-за раздельной компиляции C++
C++ Передача препроцессорных определений в командной строке
Создать функцию которая возводит число в квадрат, использовать принцип раздельной компиляции C++

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

Или воспользуйтесь поиском по форуму:
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,829
Записей в блоге: 2
Завершенные тесты: 1
15.07.2015, 11:54     Не видно определений функций при раздельной компиляции #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
То есть получается, что это возможно только для не шаблонного класса
По сути - да. Была такая штука, как export, но в c++11 её отменили.
Можно, конечно же явно инстанцировать шаблон с определенными параметрами в какой-нибудь единице трансляции, но нужно ли Вам это?
Yandex
Объявления
15.07.2015, 11:54     Не видно определений функций при раздельной компиляции
Ответ Создать тему
Опции темы

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