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

компоновка программ - C++

Восстановить пароль Регистрация
 
Greeezly
 Аватар для Greeezly
6 / 6 / 1
Регистрация: 31.08.2012
Сообщений: 230
18.12.2012, 19:02     компоновка программ #1
Вопрос собственно про сборку программ из хидеров и сишников. Не понятно пока, если мы можем описывать классы в ашниках, то почему всю программу в них не писать, и потом к мейновскому файлу не подключать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.12.2012, 19:02     компоновка программ
Посмотрите здесь:

C++ компоновка полей struct в памяти
Компоновка C++
C++ Компоновка MFC с OCX-файлом
Компоновка всей программы в один файл C++
Компоновка хедеров C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ares_Sorokin
0 / 0 / 0
Регистрация: 21.09.2012
Сообщений: 6
18.12.2012, 19:31     компоновка программ #2
Вот причина,если у нас большой класс со множеством данных и методов,то в нем намного проще ориентироваться,если в нем будет отсутствовать реализация. Поэтому в ашниках хранятся объявления данных и прототипы методов.За некоторыми исключениями конечно.
Хотя ни что не мешает тебе все в куче держать.
Надеюсь правильно понял вопрос)
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
18.12.2012, 19:49     компоновка программ #3
Дело даже не в этом, если в .h написать реализацию, то при подключении файла более чем 1 раз будет ошибка компиляции что-нибудь типа "функция void func() уже определена в файле somefile.cpp".
Да и вообще так исторически сложилось, что в .h пишутся прототипы, за редким исключением.
Greeezly
 Аватар для Greeezly
6 / 6 / 1
Регистрация: 31.08.2012
Сообщений: 230
18.12.2012, 20:09  [ТС]     компоновка программ #4
Спасибо, стало ясно.
Задам тут же вопрос, раз топик открыт: Чем отличаются структуры от классов?
WhiteP
605 / 203 / 23
Регистрация: 20.11.2012
Сообщений: 419
18.12.2012, 20:13     компоновка программ #5
Цитата Сообщение от Greeezly Посмотреть сообщение
Чем отличаются структуры от классов?
Тем, что по умолчанию модификатор доступа в struct равен public, а в классах - private

C++
1
2
3
4
class B
{
int a;
};
a - закрытая переменная. Аналогично

C++
1
2
3
4
5
class B
{
private:
int a;
}
А в

C++
1
2
3
4
struct B
{
int a;
};
аналогично

C++
1
2
3
4
5
struct B
{
public:
int a;
};
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
18.12.2012, 20:26     компоновка программ #6
Ну и наследование тоже в структурах по дефолту public, а в классах private.
activnaya
 Аватар для activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
18.12.2012, 20:42     компоновка программ #7
Цитата Сообщение от Kastaneda Посмотреть сообщение
Дело даже не в этом, если в .h написать реализацию, то при подключении файла более чем 1 раз будет ошибка компиляции что-нибудь типа "функция void func() уже определена в файле somefile.cpp".
???
C++
1
2
3
4
5
6
#ifndef HEADER_HPP
#define HEADER_HPP
namespace name{
...
}
#endif
Цитата Сообщение от Greeezly Посмотреть сообщение
Не понятно пока, если мы можем описывать классы в ашниках, то почему всю программу в них не писать, и потом к мейновскому файлу не подключать?
header.hpp содержит класс(ы) с прототипами методов, методы реализуются в объектных модулях, ну или сразу запилить их в библиотеку, не важно. Суть в том, чтобы сформировать множество абстрактных исчерпывающих методов класса. В main'е же мы оперируем уже готовыми методами как нам угодно и на свое усмотрение, а сам класс при этом остается неизменным (ну или время от времени перекомпилируется по мере выявления багов). Т.е. представь что ты пишешь класс не для отдельно взятой задачи, а для множества задач подобного типа на конечном, но не определенном заранее, временном промежутке. Двумя словами "раз и навсегда".

Добавлено через 3 минуты
Цитата Сообщение от activnaya Посмотреть сообщение
???
ааа, я поняла. конечно нельзя реализовывать метод одновременно и в header'е и *.C'шнике
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
18.12.2012, 20:54     компоновка программ #8
Цитата Сообщение от activnaya Посмотреть сообщение
???
C++
1
2
3
4
5
6
#ifndef HEADER_HPP
#define HEADER_HPP
namespace name{
...
}
#endif
И?


Добавлено через 40 секунд

Не по теме:

Цитата Сообщение от activnaya Посмотреть сообщение
Добавлено через 3 минуты

ааа, я поняла. конечно нельзя реализовывать метод одновременно и в header'е и *.C'шнике
опоздал, написал пост до этого добавления



Добавлено через 5 минут
Цитата Сообщение от activnaya Посмотреть сообщение
ааа, я поняла. конечно нельзя реализовывать метод одновременно и в header'е и *.C'шнике
дело не совсем в этом. Вот пример
C++
1
2
3
4
5
6
7
//file.h
#ifndef HEADER_HPP
#define HEADER_HPP
namespace name {
    void f(){}
}
#endif
C++
1
2
//file1.cpp
#include "file.h"
C++
1
2
//file2.cpp
#include "file.h"
при компиляции получим
Bash
1
2
3
:tmp1.cpp:(.text+0x0): multiple definition of name::f()
:tmp2.cpp:(.text+0x0): first defined here
collect2: выполнение ld завершилось с кодом возврата 1
activnaya
 Аватар для activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
18.12.2012, 21:37     компоновка программ #9
Kastaneda,
Bash
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
bash$ cat tmp.hpp tmp.C tmp1.C
//____________TMP_HPP______________
 
#ifndef TMP_HPP
#define TMP_HPP
 
#include <iostream>
 
namespace name
{
    class A
    {
    public:
        A(){}
        ~A(){}
        void foo(const char *str)
        {
            std::cout << str;
        }
    };
};
 
#endif
//___________TMP.C______________
 
#include <iostream>
#include "tmp.hpp"
 
void bar()
{
    name::A a;
    a.foo("I'm bar. called name::A::a.foo()\n");
}
//_____________tmp1.C_____________
 
#include "tmp.hpp"
 
extern void bar();
 
int main()
{
    name::A b;
    bar();
    b.foo("I'm main. called object name::A::b.foo()\n");
 
    return 0;
}
bash$ g++ tmp.C tmp1.C
bash$ ./a.out 
I'm bar. called name::A::a.foo()
I'm main. called object name::A::b.foo()
bash$
Добавлено через 1 минуту
в tmp.C директива #include конечно лишняя. Забыла просто ее убрать.

Добавлено через 6 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
Вот пример
кстати этот пример немного некорректен т.к. используется структурный подход. В данном случае речь идет об ООП, классах и методах.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
18.12.2012, 21:59     компоновка программ #10
Цитата Сообщение от activnaya Посмотреть сообщение
кстати этот пример немного некорректен т.к. используется структурный подход. В данном случае речь идет об ООП, классах и методах.

Не по теме:

Некоторые вещи хорошо выражаются именно глобальными функциями. Статический метод класса, метод синглтона или просто глобальная функция в неймспейсе — не суть важно. От этого менее глобальными они не становятся. А утверждать, что глобальные функции в неймспейсах ересь, — это ООП головного мозга.


Наоборот, это вы лукавите с extern void bar();. Это то же самое, что подключить h-файл с прототипом в этом месте. Это не контрпример к проблеме повторного определения.
activnaya
 Аватар для activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
18.12.2012, 22:18     компоновка программ #11
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
А утверждать, что глобальные функции в неймспейсах ересь, — это ООП головного мозга.
и как же тогда решить проблему повторного определения? если не прибегать к показанному мной способу в виде extern void bar();

Добавлено через 5 минут
ну понятно. прототип же.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
18.12.2012, 22:36     компоновка программ #12
Цитата Сообщение от activnaya Посмотреть сообщение
и как же тогда решить проблему повторного определения?
inline. Кстати, в последнем примере с методом класса этот метод inline. Определить его вне класса - та же ошибка линковки.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2012, 05:20     компоновка программ
Еще ссылки по теме:

Переполнение стека и несовместимая компоновка dll C++
Внутренняя компоновка с модификатором const C++
C++ Компиляция, компоновка, линковка (undefined reference to.)

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

Или воспользуйтесь поиском по форуму:
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
19.12.2012, 05:20     компоновка программ #13
activnaya, ну как бы суть уже сказали
Цитата Сообщение от gray_fox Посмотреть сообщение
Кстати, в последнем примере с методом класса этот метод inline. Определить его вне класса - та же ошибка линковки.
а инлайн функции/методы имеют область видимости, ограниченную файлом. Поэтому в этом примере можно было бы обойтись даже без нэймспейсов, все бы так же работало.
Yandex
Объявления
19.12.2012, 05:20     компоновка программ
Ответ Создать тему
Опции темы

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