LINUX.ORG.RU

Научите создавать многофайловые проекты.


0

2

Речь про многофайловые c++ / Qt проекты.

1) Нет полного (да и среднего тоже) понимания в каких случаях нужно что-то выносить в другой файл. 2) Даже когда собрался что то вынести в другой файл затрудняюсь это сделать.

Вот сейчас например решил отделить основной код(делает преобразование картинок). От Гуи в другой файл. И оно даже компилироваться не хочет, не поделитесь статейкой или книжкой на эту тему?

Перемещено mono из talks


В идеале (поскольку Qt превращает кресты почти что в яву) - один класс == 2 файла (hpp/cpp).

svr4
()
Ответ на: комментарий от svr4

Проблема в том что у меня в одном классе идет взаимодействие с другим(который определен в другом файле)

knotri
() автор топика
Ответ на: комментарий от knotri

кому-то щас посоветуют почитать книжку про язык сначала и самозабаниться

belkabelka
()

А в чем проблема-то? Сначала помучайся с одним файлом. Как поймешь, что разобраться в файле длиннее тысячи-двух тысяч строк — нереально, начнешь кромсать и разбивать по разным файлам. Потом замучаешься Makefile вручную писать, и перейдешь на cmake...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от knotri

Мм, ну и чо? Это норма (ц). Паблики и должны взаимодействовать с другим классом.

svr4
()
Ответ на: комментарий от Eddy_Em

Потом замучаешься Makefile вручную писать, и перейдешь на cmake...

Я Qt использую, в pro файле пишу какие библиотеки нужно подключить и прочее. Я не особо разбираюсь в процессе компиляции.

knotri
() автор топика

Не забывай про "стражей" заголовочных файлов; включай все глобальные переменные, которые могут использоваться в других файлах, в заголовочные как extern; включай объявления всех функций и структур данных, которые будут вызываться из других файлов, в заголовочные файлы; функции, которые только в одном файле используются, можно для уверенности обзывать static (чтобы конфликтов имен не было, если что) и т.д., и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Я про общий случай, а не конкретные культи.

Я просил статейку какую то, где примеры были бы, объяснения.

knotri
() автор топика

Смотри, берешь комментарий типа /**/ и делаешь его длинным. Разбиваешь им логические куски программы, готово. Можно ещё дописвывать как называется некоторая часть программы.

И да, расскажи, сколько у тебя там строк, что ты программы разбиваешь?

Deleted
()
Ответ на: комментарий от Deleted

Лучше сразу учиться нормально код писать, а то понапишут кода по тысяче строк в одной функции, фиг потом разберешь

pv0
()

Вообщем.

Берешь читаешь K&R. @ Читаешь Страуструпа. @ Понимаеш что с++ мертвый и не нужный язык. @ Читаешь Dive into python.

По сабжу создаешь .h файл, в нем объявляешь класс. В .cpp поясняешь за этот класс.

Например.

//foo.h

#ifndef FOO_H
#define FOO_H

class foo{
public:
int test (int);
};

#endif
//foo.cpp

#include "foo.h"

int foo::test(int x)
{
//bla bla bla
return x
}

Дальше просто подключаешь foo.h, где нужно.

nickionn ★☆
()
Последнее исправление: nickionn (всего исправлений: 1)
Ответ на: комментарий от Deleted

Пока не много (чуть больше 500). Дело в том что есть явно интерфейс программы, и не интерфейс.

knotri
() автор топика
Ответ на: комментарий от knotri

1. Любую книгу про основы C++ (Прата, к примеру).
2. Книжку про Qt от создателей фреймворка. (Бланшет, Саммерфилд - QT4 Программирование GUI на С++)

Вкратце:
1. Cоздаешь «ImageProcessing.h»-файл, содержащий объявление класса, который будет работать с твоими картинками. Определяешь в нем методы «преобразования картинок»:

#ifndef IMAGEPROCESSING_H
#define IMAGEPROCESSING_H

#include <QObject>
#include <QWidget>

class ImageProcessing : public QObject
{
    Q_OBJECT
public:
    bool myCoolFunc1();
    bool myCoolFunc2();
    ImageProcessing();
    ~ImageProcessing();
}

#endif //MAINWINDOW_H

2. Создаешь «ImageProcessing.cpp»-файл, инклудишь в него «ImageProcessing.h» и пишешь реализацию методов:

#include "ImageProcessing.h"

#include <QObject>
#include <QWidget>

ImageProcessing::ImageProcessing()
{
    /* under construction */
}
    
bool ImageProcessing::myCoolFunc1() 
{
   return true;
}

bool ImageProcessing::myCoolFunc2()
{
   return false;
}

ImageProcessing::~ImageProcessing() 
{
   /* under construction */
}

3. После инклудишь «ImageProcessing.h» в необходимое место в программе, к примеру в GUI («MyAppGui.cpp»), создаешь объект (в примере ниже - на стеке) и вызываешь метод:

#include "MyAppGui.h"
#include "ImageProcessing.h"
...
bool MyAppGui::convertImage()
{
    ...
    ImageProcessing imgProc;
    return imgProc.myCoolFunc1();
}
...

4. Можно создать объект в куче, который будет доступен тебе не только в одном методе. Для этого в «MyAppGui.h» следует объявить указатель на объект класса ImageProcessing:

#ifndef MYAPPGUI_H
#define MYAPPGUI_H

#include "ImageProcessing.h"

#include <QObject>
#include <QWidget>

class MyAppGui : public QWidget
{
    Q_OBJECT
    ImageProcessing *imgProc;
public:
    MyAppGui();
    ~MyAppGui();
    ...
}
#endif //MYAPPGUI_H

5. А затем в «MyAppGui.cpp», инициализировать этот указатель, например, в конструкторе MyAppGui():

#include "MyAppGui.h"
...
MyAppGui::MyAppGui()
{
    ...
    imgProc = new ImageProcessing;
    ...
}
...

После этого можно смело вызывать его методы там, где это необходимо. Как-то так. Старался объяснить наиболее просто. За подробным разъяснением лезь в книжки.

EXL ★★★★★
()
Ответ на: комментарий от knotri
neko@neko-N750JV:~/src/test$ cat > 1.c
int main (){


 do_stuff();}
neko@neko-N750JV:~/src/test$ cat > 2.c
void do_stuff(void){


puts ("I did stuff!");}
neko@neko-N750JV:~/src/test$ gcc 1.c 2.c
neko@neko-N750JV:~/src/test$ ./a.out
I did stuff!
takino ★★★★★
()
Последнее исправление: takino (всего исправлений: 1)
Ответ на: комментарий от knotri

Забыл добавить, что потом эти файлы необходимо добавить в проектный файл («*.pro» или «CMakeLists.txt»). Если ты пишешь код в Qt Creator - заюзай функцию «Add new...» -> «C++ Class», это тебе создаст сразу и «*.cpp» и «*.h» файлы с примером кода и заодно добавит тебе их в проект.

EXL ★★★★★
()

Вообще, имхо, универсальный ответ - если ты прочитал исходник через пару недель после последней правки и не понял, что он делает за 10 минут, то надо разбивать на части.

takino ★★★★★
()
Ответ на: комментарий от takino

У него там кресты и Qt. Если он так будет делать - максимум, что получит - do_stuff’ was not declared in this scope

EXL ★★★★★
()

K&R, «Алгоритмы + структуры данных = программы»

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от takino

Я это к тому, что C и C++ несмотря на свою похожесть всё-таки разные:

exl@exl-Lenovo-G560e:~/SandBox > cat 1.cpp 
int main () { do_stuff(); }

exl@exl-Lenovo-G560e:~/SandBox > cat 2.cpp 
#include <cstdio>
void do_stuff(void) { puts ("I did stuff!"); }

exl@exl-Lenovo-G560e:~/SandBox > g++ 1.cpp 2.cpp 
1.cpp: In function ‘int main()’:
1.cpp:1:24: error: ‘do_stuff’ was not declared in this scope

exl@exl-Lenovo-G560e:~/SandBox > cat 1.cpp 
#include "2.h"
int main () { do_stuff(); }

exl@exl-Lenovo-G560e:~/SandBox > cat 2.cpp 
#include "2.h"
#include <cstdio>
void do_stuff(void) { puts ("I did stuff!"); }

exl@exl-Lenovo-G560e:~/SandBox > cat 2.h
void do_stuff(void);

exl@exl-Lenovo-G560e:~/SandBox > g++ 1.cpp 2.cpp 

exl@exl-Lenovo-G560e:~/SandBox > ./a.out 
I did stuff!

Кстати, может кто-нибудь популярно объяснить, почему для компилятора C не нужна обязательная декларация (см. пример выше), а для C++ нужна?

EXL ★★★★★
()
Ответ на: комментарий от EXL

это в искусственное ограничение. кстати в c'99 явная декларация вроде тоже обязательна.

val-amart ★★★★★
()
Ответ на: комментарий от EXL

Угу %)
Я и не спорю. Ответил, что знал; оказался не прав.

takino ★★★★★
()
Ответ на: комментарий от takino

надо разбивать на части.

и писать комменты

Deleted
()
Ответ на: комментарий от Eddy_Em

функции, которые только в одном файле используются, можно для уверенности обзывать static (чтобы конфликтов имен не было, если что)

Сишник детектед! У ТСа кресты, поэтому не static, а anonymous namespace.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от knotri

Я Qt использую

Так а в чем тогда проблема? QtCreator, ЕМНИП, сам создает для каждого нового класса .h и .cpp

Ну а дальше просто #include "your_header.h"

solovey ★★
()

Крестопоклонники!

Нет полного (да и среднего тоже) понимания в каких случаях нужно что-то выносить в другой файл.

Это потому-что ты бутерброт неправильно ешь. В кутях всё делается наследованием от уже существующих, или использованием уже существующих классов. Пойми что такое класс вообще, займись проектированием, пойми, что всё что ты написал - уг и перепеши всё с нуля. Пришей 100 пуговицСделаей так раз 5ть, набъёшь руку. Вот тогда будет результат.

А вообще бросай ты это дело. Спп - тупиковая ветвь эволюции. Я тебе это говорю как регулярно его использующий.

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)

1. Раздели в своей голове все на объявление класса/функции и его реализацию.
2. Все объявление в .h, всю реализацию в .cpp
3. #include «FileName.h» лишь вставляет содержимое файла вместо самой этой директивы
4* Подумать, зачем в .h нужны #ifdef/#define в самом начале.

После этого пользуйся золотым правилом: один класс - один хидер. И лучше, если один cpp.

trex6 ★★★★★
()
Ответ на: Крестопоклонники! от nanoolinux

А вообще бросай ты это дело. Спп - тупиковая ветвь эволюции.

А что не тупиковая? Интерпретируемыми ЯП пользоваться не хочу.

knotri
() автор топика
Ответ на: комментарий от knotri

не слушай этого наркомана и изучай кресты или петон.

x0r ★★★★★
()

Если хочешь писать на c++, осиль его уже. Или иди быдлокодь на жобке.

anonymous
()
Ответ на: комментарий от knotri

Haskell, для неосиливших - Java (в т.ч. другие языки той же платформы), для хипстеров - D & Go & Rust.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.