Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исходные файлы с описанием класса, Как правильно 
:(
    Опции темы
efpies
Дата 18.1.2011, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



Здравствуйте.
Очень ламерский вопрос, на самом деле.

У меня в проекте несколько классов. Как было бы правильно их разбивать по файлам? Каждый класс в отдельный cpp-файл? Или в h-файл? Или в h-файле - прототипы и константы, а в cpp, который подключён к h, - описание? Как правильно?
PM MAIL   Вверх
KaraKum
Дата 18.1.2011, 16:32 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Некоторые фанатики каждый класс описывают в отдельном .h-файле (называя файл так же как и класс но только маленькими буквами и разделяя слова пробелами - получается ужасно).
Можно делить объявления классов по логическим признакам. Например классы отвечающие за графику - в одном файле; за логику - в другом. Общих нареканий в этой области нет (в отличии от, например, по оформлению кода (самая известная - GNU-style)).
Код определения функций можно писать прямо в объявлении этих функций (в .h-файле) если подразумевается что файл будет подключаться к проекту только в одном месте (что как раз это подчёркивает)
Не забывать что можно писать и "#include "definition.cpp"" - то есть вообще обойтись без header'ов  smile

Добавлено через 3 минуты и 43 секунды
В остальном могут быть только какие-то частные нарекания. Например какие-то глобальные переменные (как же без них) можно определить в "globals.cpp":
Код

namespace Globals
{
     int someGlobalVariable = 0;
     ClassName *someGlobalClassInstance = new ClassName;
}//namespace Globals

И создать вот такой "externs.h", который можно подключать в любом другом файле где нужно использовать глобальные переменные:
Код

#ifndef EXTERNS_H
#define EXTERNS_H

namespace Globals
{
     extern int someGlobalVariable;
     extern ClassName *someGlobalClassInstance;
}//namespace Globals

#endif//#ifndef EXTERNS_H


Добавлено через 9 минут и 21 секунду
Вообще, все эти проблемы решаются как сами собой разумеющиеся после должного проектирования программы (перед её написанием или в процессе). Для этого можно пользоваться средствами ООПTDD и общие принципы проектирования рисованием графовUML-диаграмм...
PM MAIL WWW   Вверх
mes
Дата 18.1.2011, 17:08 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(KaraKum @  18.1.2011,  15:32 Найти цитируемый пост)
Не забывать что можно писать и "#include "definition.cpp"" - то есть вообще обойтись без header'ов  

и нажить проблем smile



--------------------
PM MAIL WWW   Вверх
KaraKum
Дата 18.1.2011, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Цитата(mes @ 18.1.2011,  18:08)
Цитата(KaraKum @  18.1.2011,  15:32 Найти цитируемый пост)
Не забывать что можно писать и "#include "definition.cpp"" - то есть вообще обойтись без header'ов  

и нажить проблем smile

Именно.
PM MAIL WWW   Вверх
mes
Дата 18.1.2011, 17:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(KaraKum @  18.1.2011,  15:32 Найти цитируемый пост)
Некоторые фанатики каждый класс описывают в отдельном .h-файле

далеко не только фанатики... 


Это сообщение отредактировал(а) mes - 19.1.2011, 13:29


--------------------
PM MAIL WWW   Вверх
KaraKum
Дата 18.1.2011, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Цитата(mes @ 18.1.2011,  18:09)
Цитата(KaraKum @  18.1.2011,  15:32 Найти цитируемый пост)
Некоторые фанатики каждый класс описывают в отдельном .h-файле

далеко не только фанатики фанатики...

Скорее-всего я неясно высказался.
Иногда бывает что какие-то структуры используются только внутри какой-то одной функции - такие структуры вполне логично объявлять внутри самой этой функции, однако некоторые ФАНАТИКИ выделят для этой структуры отдельный файл, назвав этот файл в её честь.  smile 
PM MAIL WWW   Вверх
borisbn
Дата 18.1.2011, 21:06 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



2 TS:  пишу с КПК в автобусе, поэтому коротко: KaraKum дал тебе ОЧЕНЬ плохие советы. Что про несколько классов в одном h-нике, что инклюд срр-шника, что про глобальные переменные. Чуть позже подробнее отпишусь 

Это сообщение отредактировал(а) borisbn - 18.1.2011, 21:37


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
KaraKum
Дата 18.1.2011, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Опаньки  smile 
Ну вот - TS в чрезвычайном режиме спасли от моих смертельных советов  smile

Добавлено через 55 секунд
Кстати, инклудить .cpp-файлы я не советовал - сказал лишь что это возможно. А вот объявление нескольких классов в одном хедере и глобальные переменные - это советовал (описал как это делать).
PM MAIL WWW   Вверх
borisbn
Дата 19.1.2011, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(KaraKum @  18.1.2011,  22:42 Найти цитируемый пост)
не советовал - сказал лишь что это возможно

у новичков часто строится такая цепочка "возможно-так можно делать-так делают-так делают все-так нужно делать". Возможно ещё создавать функции на 2000 строк, делать такие конструкции ( пару лет назад достался проект по наследству, так я этот кусок сохранил, чтобы показывать как не надо делать )
Код

// Построение гистограммы
Histogramm[szMin - MIN_LEVEL + int(*pMP++)]++;

и т.п., однако сообщать новичкам, что это всё возможно IMHO не стОит.
Теперь о нескольких классах в одном хедере. Если класс настолько маленький и простенький, что для него не нужен отдельный файл, то его и создавать не нужно, скорее всего можно обойтись "свободными" функциями ( исключения составляют лишь функторы, но с приходом стандарта 0x00 и в них не будет особой необходимости ). Если же класс сложнее, чем пару функций get/set и если он создан для того, чтобы повторно его использовать ( и не в одном проекте, а в многих последующих ), то его просто необходимо вынести в отдельный файл. Так ведь даже удобнее.
А глобальные переменные ( не константы ) - вообще зло, т.к. сегодня тебе хватает производительности, а завтра - нет, и приходится распараллеливать программу, делать несколько потоков... далее, думаю, понятно.

P.S. Кажется TS уже забыл о нас, и всё это превращается во флуд. Предлагаю засим закончить smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
efpies
Дата 19.1.2011, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



TS мониторит тему потихоньку)
Спасибо за советы.

Почему у меня возник такой вопрос: вот пишут, что
Цитата

Заголовочный файл в общем случае может содержать любые конструкции языка программирования, но на практике исполняемый код (за исключением inline-функций в C++) в заголовочные файлы не помещают.


Ну хорошо, сейчас у меня каждый класс в отдельном h-файле (каждый строк на 200, потому всё в один файл пихать - это будет кровавое месиво, тем более каждый класс считай как модуль), который имеет имя такое, как класс. Насколько это верно с учётом этой цитаты?) Да и вообще при каком-либо изменении какого-либо класса нужно сначала сделать build, а только потом run (видимо, сказывается специфика h-файлов), что сказывается на отладке не лучшим образом. Вот мне и подумалось, а не в cpp-файлы ли помещать их описание и т.д.? Ну и соответственно, что будет являться "хорошим стилем".
PM MAIL   Вверх
borisbn
Дата 19.1.2011, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



efpies, самая общепринятая практика следующая: в h-файлах класс описывается, а в cpp-файлах - определяется. Описание класса - есть интерфейс (договор, контракт) между тем, кто его создаёт и тем, кто его будет использовать. Определение класса - это уже не договор, а испольнение договора, причём только тем, кто его создаёт. При этом, если ты изменяешь договор между разработчиком класса и его потребителем, то тебе необходимо перекомпилировать и сам класс, и те исходники, которые его используют. Если же ты меняешь только ход исполнения договора, при этом контракт остаётся нетронутым, то достаточно только перекомпилировать исходник класса. А вообще без перекомпиляции при изменении в Си/Си++ никак. Это не скриптовый язык.
Вот пример нормальной организации класса и его использования:
SomeClass.h
Код

#if !defined( _SOME_CLASS_H_INCLUDED_ )
#define _SOME_CLASS_H_INCLUDED_ 

class SomeClass {
public:
  SomeClass();
  ~SomeClass();
  void foo();
private:
  int m_x;

  void bar();
};
#endif //!defined( _SOME_CLASS_H_INCLUDED_ )


SomeClass.cpp
Код

#include "SomeClass.h"

SomeClass::SomeClass()
  : m_x( 0 )
{
}

SomeClass::~SomeClass() {
}

void SomeClass::foo() {
}

void SomeClass::bar() {
}


SomeClassUsing.h (использование SomeClass)
Код

#if !defined( _SOME_CLASS_USING_H_INCLUDED_ )
#define _SOME_CLASS_USING_H_INCLUDED_ 

class SomeClass;

class SomeClassUsing {
public:
  SomeClassUsing();
  ~SomeClassUsing();
private:
  SomeClass * m_someClass;
};
#endif //!defined( _SOME_CLASS_USING_H_INCLUDED_ )


SomeClassUsing.cpp (использование SomeClass)
Код

#include "SomeClassUsing.h"
#include "SomeClass.h"

SomeClassUsing::SomeClassUsing() {
  m_someClass = new SomeClass();
}

SomeClassUsing::~SomeClassUsing() {
  delete m_someClass;
}




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
KaraKum
Дата 19.1.2011, 13:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Вот тут вот рисованные карандашом картинки могут быть интересны.
PM MAIL WWW   Вверх
efpies
Дата 19.1.2011, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



borisbn, KaraKum, спасибо за наглядные ответы! smile


Цитата(borisbn @  19.1.2011,  11:54 Найти цитируемый пост)
А вообще без перекомпиляции при изменении в Си/Си++ никак. Это не скриптовый язык.

Это понятно, просто либо компилятор сам перекомилирует, либо я это делаю насильно. Это я имел в виду.

Возник такой вопрос: к примеру, у меня есть 2 h-файла и 2 соответствующих cpp-файла (то есть, как Вы описали). Что в конечном итоге включается в использующий файл? Ну я имею в виду, что если мы включим в main.cpp SomeClassUsing.h, он же не будет знать о существовании SomeClassUsing.cpp, поскольку в заголовочном файле он никак не затрагивается. Или компилятор будет знать "по умолчанию" о существовании cpp-файла, поскольку имена одинаковые?
PM MAIL   Вверх
KaraKum
Дата 19.1.2011, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Я уже даже боюсь отвечать, ато теперь не из автобуса "по рации" сообщат о некомпетентности, а в квартиру постучат и конвоируют  smile 

"Превращение исходного кода в исполняемый" выполняется в два этапа: компиляция и, затем, компоновка (есть ещё препроцессор, но его относят к компиляции).
В процессе компиляции формируется никак не связанный набор функций (в том числе и main()). Процесс компиляции в местах вызовов функций лишь проверяет факт их описания (существования) и, конечно, вызываемые параметры. При компоновке на места вызовов функций располагаются уже настоящие адреса расположения этих функций (их исполняемые варианты, созданные в процессе компиляции) - если компоновщик не находит какую-либо скомпилированную функцию, то будет ругаться и откажется компилировать.
Поэтому если не указать .cpp файлов, то процесс компиляции может завершиться успешно, но компоновка нет.
PM MAIL WWW   Вверх
mes
Дата 19.1.2011, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(efpies @  19.1.2011,  20:30 Найти цитируемый пост)
. Или компилятор будет знать "по умолчанию" о существовании cpp-файла, поскольку имена одинаковые? 

каждый .cpp файл компилится отдельно, но вместе со всеми включениями..
для того чтоб знать какие вы файлы хотите скомпилить и с чем их собрать используют make-файл..
IDE позволяет использовать его неявно для пользователя.. 





--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.