LINUX.ORG.RU

«зеленка» работает с указателями и проч.


0

0

Отчего может так быть, что в режиме отладки программа (С++) работает нормально, а при ее естественном запуске возникают исключения. Мой товарищ сказал, что, возможно, это из-за некорректной работой с памятью (указатели и проч.) В связи с этим он порекомендовал программу vargrind (с его слов по телефону)- мол она отлавливает некорректную работу с памятью. Подскажите, пожалуйста ссылку...

И, раз уже "дорвался до микрофона", как правильно прописывать описание класса: писать в .h файлах include <> (или для своих классов "") или class ..., а в .cpp писать include. Единственную разницу понял, что если в .h описывается объект, а не указатель, то требуется тут же писать include об классе этого объекта. Это понятно.


Поищи в гугле: valgrind Download

anonymous
()

Принято в *.h - писать объявление функций или классов,
в соответствующих  *.c/*.cpp  - реализацию. 

Конечно нужно в  *.c/*.cpp  включать описание, 
что делает:  #include "*.h" 
Для своих классов пишут обычно: #include "*.h"
 для библиотечных:  #include <*.h>
Все это делается для удобства, так как
один и тотже заголовок часто должен быть виден из
других *.c/*.cpp - файлах, где используется функция или
класс. По принятым негласно соглашениям легко разбираться
в большой программе. 
Это все относится к стилю программирования. 
Не важно указатель или нет на тип переменной
(класс - это тип в языке С++)
Тип должен быть описан, описание лежит в "*.h"
значит нужно куда-то включить.
Или нужно писать что внешний.   
extern  class  clNameClass / extern void name_function()
Тогда во время компиляции компилятор не будет искать
определение а поверит "на слово".
Если Ваш код не будет использован другими
и не нужно будет другим людям сопровождать программу,
то как Вы пишите не волнует никого кроме Вас.
В противном случае лучше придерживаться некоего
стиля по умолчанию принятого и используемого
в профессиональных коллективах, поэтому и смотрят код
при приеме на работу. 
Есть книжка Ален, Голуб "Правила программирования на С и C++"
Хорошая книжка, маленькая но вполне исчерпывающая.
(это не эффективное программирование, а правила)
В электронном виде не видел, но в Ленинке наверняка есть.

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

Я прекрасно знаю, что в .cpp пишут include его .h и поначалу так делал. Просто в примерах по QT увидел, что в .h стремятся писать class <>, а включают .h в .cpp (говорю о стандартных классах, но опыт можно расширить и на чужеродные для данного класса классы). Вот я и засомневался: что правильнее и эффективнее (может, для быстрой компилятора или чего еще)?

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

Честно говоря может и хватил. :)
Писал быстро.
А как нужно ? 
Объявления класса нет,
 как его объявить так что-б
компилятор понял как нужно и линковка прошла.
Подскажите ?

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

Без слов, что лучше :

1.

*.h: class qvbox; *.cpp: #include <qvbox.h>

или 2.

*.h: #include <qvbox.h>

То же применительно к моим классам, используемым из данного класса.

Разговаривайте, пожалуйста, со мной, а не меж собой. >8-)

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

> А как нужно ?

class clNameClass /*без extern*/

> Объявления класса нет,

Как раз таки у класса нет определения - только объявление. Это ведь тип данных. Определения есть у методов класса.

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

Вы можите без сокращений не понятно.

>...что в .h стремятся писать class <>, 
>а включают .h в .cpp

Вы о шаблонах что-ли ?
Что значит выражение: "class <>" ?
И что значит: ">...что в .h стремятся писать class <>"
а куда обычно кладут объявления, разве не в  *.h ? 

Может я чего упустил или забыл ?
Приведите небольшой примерчик.

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

Уточните пожалуйста Ваш вопрос.
Самому интересно.

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

> Разговаривайте, пожалуйста, со мной, а не меж собой. >8-)

Это можно. Пока мы добрые ;)

Честно говоря, я так до сих пор до конца и не понял из твоих объяснений, что где объявлено/определено и где используется :) Поэтому объясню на примере. В myclass.h - объявление класса, в myclass.cpp - определение, в myprogram.cpp - использование.

/***** myclass.h *****/
#ifndef __MYCLASS_H__
#define __MYCLASS_H__

#include ... /* ТОЛЬКО ТО, что нужно для ОБЪЯВЛЕНИЯ (не определения методов) класса */

class MyClass
{
...
protected:
void methodProt( int Arg );
...
public:
void methodPublic( int Arg );
...
};

#endif __MYCLASS_H__

/***** myclass.cpp *****/
#include "myclass.h"

#include ... /* ТО, ЧЕГО НЕ ХВАТАЕТ для ОПРЕДЕЛЕНИЯ */

void MyClass::methodProt( int Arg )
{
...
};

void MyClass::methodPublic( int Arg )
{
...
};

/***** myprogram.cpp *****/
#include "myclass.h"
...
MyClass myVar = MyClass();
...

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

Так я и говорю об объявлении. 
Тип то где-то должен быть описан, ведь так?

Компилятор его должен найти в области видимости.
Я говорил о том, что если тит не описан и компилятору не известен этот тип
он ругнется уже на этапе компиляции.
а если ему подсунуть "extern", он проглотит.
Делая #include "" / #include <>
мы авно указываем где искать. Считая что пути прописаны.

А если не указать: #include "clName.h"

а в нашей функции использовать этот
самый тип: clName. То нас не поймут.
Ему нужно сказать непереживай дорогой и поверь мне.
Может у нас все определяется в процессе выполнения.

Хотя похоже вспомнил с классами такая штука не проходит.
Только с функциями. Поэтому и приходиться извращаться при
написанни компонентных динамических библиотек (под Unix :)) ).
Похоже чуть забыл, Sorry.

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

>Без слов, что лучше :
>1. *.h: class qvbox; *.cpp: #include <qvbox.h>
>или 2. *.h: #include <qvbox.h>
>
>То же применительно к моим классам, используемым из данного класса.
>Разговаривайте, пожалуйста, со мной, а не меж собой. >8-)

1-ый вариант годится для случая, когда в твоем классе используются лишь указатели на QVBox.
2-ой вариант - во всех остальных случаях (наследование и/или инкапсуляция).

Надо уже FAQ делать)

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

конечно так нельзя , но под class <> я имел в виду ( без конкрет. указания) имя стандартного класса, например. Шаблоны я здесь не обсуждаю. Я просто хочу получить простой ответ: что лучше позднее объявление или раннее (или как их еще там - см. пример выше с 2-мя вариантами).

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

Спасибо за лаконичный ответ мне(!!!)

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

Я не успеваю отвечать.
Я поня Ваш вопрос.

Это дело вкуса. Не больше не меньше.
вообще в Unix/Linux принято включения
делать в  "*.h" так нагляднее и не засоряет
реализацию, т.е. "*.cpp" - файлы.

1 - вариант:
В "*.cpp" просто указываем один единственный
"*.h" - файл, который относится к "c"-файлу,
и в этом "*.h" - файле все пихаем

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


2-вариант.
Все "*.h" + <*.h> пихаем в "*.cpp"
получаем большущую бороду в каждом "*.cpp" -файле.
Очень полохо, особенно когда мы меняем
включаемые "*.h" - файлы, вводим в них новый тип,
тогда мы должны во всех "*.cpp" - файлах, 
где есть упоминание этих уже измененных "*.h"
перед ним вставить Тот самый довесок.
Проблема еще та, кроме того это проявляется обычно 
во время пересборки проекта. Жуть. 
Проекты дольшие много каталогов, файлы разбросаны.

3-вариант.
Есть некий выход, из этой ситуации, 
мы локализуем наши "*.h" - файлы в одном
и называем его по имени каталога в котором хранится
все наше богатство.
includeServerBody.h
Такой файл есть в каждом каталоге
includeSql.h
...
В этих самых "целевых" - includ-ах мы и прописываем 
то что нам нужно.
А его включаем 1 строчкой во все "*.cpp" - лежащие 
в нашем каталоге, после него свой "*.h"
Все include - в "*.cpp"

// clName.cpp
#include "includeServerBody.h"
#include "clName.h"

clName::clName()
{
  ...
} // clName::clName()
...

Тогда если есть изменения мы быстренько вставляем 
то что нужно в один файл
includeServerBody.h
и все изменения пройдут автоматом.
Перекрестных ссылок нет, так как ни в одном
"*.h" - файле нет включений.

Единственное что требуется, так это четко соблюдать
последовательность включений в этих самых
"includeServerBody.h", includeSql.h, ..
предупреждение нельзя включать
в  includeServerBody.h  файл  includeSql.h
будут перекрестные ссылки.


>Разговаривайте, пожалуйста, со мной, а не меж собой. >8-) 

:))))  Вы молодец.

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

Спасибо, собственно поэтому я этот вопрос и поднял. У меня связи явно циклически закручены.

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

Спасибо что ответили, думал, что обиделись.
Но лучше бы сразу писали полностью думай, гадай, что к чему. :)

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