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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменяемые глобальные переменные, И снова extern 
:(
    Опции темы
efpies
Дата 22.2.2012, 02:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Много гуглил, ничего полезного не нашёл (в учебнике Дейтелов даже примера кода нет, всё, предполагается, должно быть понятно не так).

Ну окей.
Хочу задать масштаб отрисовки в одном месте (передавать как параметр в куче мест как-то накладно).

constants.h
Код

#ifndef ConstantsH
#define ConstantsH

double scale = 1.0;

#endif


Unit1.cpp
Код

#include "constants.h"
#include "Edge.h"

extern double scale;
 
//---------------------------------------------------------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
     scale = 5.0;
     Edge *e;
     // Init
     e->draw();
     delete e;
}


Edge.h
Код

#include "constants.h"

extern double scale;

void Edge::draw ()
{
    canvas->PenPos = TPoint (x1*scale, y1*scale);
    canvas->LineTo(x1*scale, y2*scale);
}


scale в draw равен 1. Что я делаю не так?
PM MAIL   Вверх
t_gran
Дата 22.2.2012, 06:50 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



efpies, мне интересно как ваш код вообще работает. Вы посмотрите на эти строчки:

Unit1.cpp
Код

   // ...
   Edge *e;
   e->draw();
   delete e;
   // ...

Ничего странного не замечаете? Вы даже объект не создали, а пытаетесь вызвать метод draw, да ещё потом удаляете не созданный объект. Поразительно.  smile

Теперь по части extern.
Переменную как раз в заголовочном файле вы должны описать как extern, а реализовывать её уже в одном из cpp файлов. К примеру так:

constants.h
Код

#ifndef ConstantsH
#define ConstantsH
extern double scale;
#endif


Unit1.cpp
Код

#include "constants.h"
#include "Edge.h"
 
double scale = 1.0;

//---------------------------------------------------------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
     scale = 5.0;
     Edge *e = new Edge;
     // Init
     e->draw();
     delete e;
}


Edge.h
Код

#include "constants.h"

void Edge::draw ()
{
    canvas->PenPos = TPoint (x1*scale, y1*scale);
    canvas->LineTo(x1*scale, y2*scale);
}


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

Это сообщение отредактировал(а) t_gran - 22.2.2012, 07:08


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
efpies
Дата 22.2.2012, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(t_gran @ 22.2.2012,  06:50)

Ничего странного не замечаете? Вы даже объект не создали, а пытаетесь вызвать метод draw, да ещё потом удаляете не созданный объект. Поразительно.  smile


Нет, не замечаю, просто не хочу сюда копировать 10 строк инициализации, к делу не относящейся smile

Действительно, так работает, спасибо. Что интересно, это расходится с вот этой статьёй, или я чего-то не понимаю.

Это сообщение отредактировал(а) efpies - 22.2.2012, 10:59
PM MAIL   Вверх
mes
Дата 22.2.2012, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(efpies @  22.2.2012,  09:38 Найти цитируемый пост)
Что интересно, это расходится 

расходится в чем ?


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



Цитата

Нет, не замечаю, просто не хочу сюда копировать 10 строк инициализации, к делу не относящейся 

Не подумайте, что придираюсь, но тогда и delete к делу не относится.

Цитата

Что интересно, это расходится с вот этой статьёй, или я чего-то не понимаю.

Абсолютно не расходится. Вы просто не так поняли. Заметьте, что в статье фигурируют только cpp файлы. О заголовочных файлах там ни слова. К тому же, нужно чётко понимать, что такое h файл, и что переменные в них никогда не объявляются.


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mes
Дата 22.2.2012, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(t_gran @  22.2.2012,  12:59 Найти цитируемый пост)
что такое h файл, и что переменные в них никогда не объявляются. 

 smile 


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



mes, поясните. Я что-то не то написал? Или вы к тому что я не так выразился и вместо инициализации употребил слово объявление?

Это сообщение отредактировал(а) t_gran - 22.2.2012, 14:51


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
feodorv
Дата 22.2.2012, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(t_gran @  22.2.2012,  13:59 Найти цитируемый пост)
нужно чётко понимать, что такое h файл, и что переменные в них никогда не объявляются. 

Деление кода на .c-часть и .h-часть в достаточной степени является вопросом соглашения. Не принято объявлять переменные в заголовочных файлах, но это не значит, что там их объявлять совсем нельзя. Можно, но для ограниченного круга задач.

Можно ведь и .c-файл заинклюдить:
Код

#include "mycode.c"

никто не запрещает. 

А бывает, что требуется в нескольких проектах (небиблиотечным образом) включение одного и того же кода. И чтобы не писать каждый раз
Код

#include "mycode.h"
#include "mycode.c"

можно весь код из mycode.c (вместе с объявлениями переменных etc) запихнуть в mycode.h. Получится просто
Код

#include "mycode.h"

Но нужно, конечно, понимать, что и зачем делаешь smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
mes
Дата 22.2.2012, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(t_gran @  22.2.2012,  13:43 Найти цитируемый пост)
Я что-то не то написал? 

 
Цитата

 никогда не

не верю что нельзя определить переменную в хидере smile

ну и маленькое замечание, в данном контексте не объявление, а определение
  объявление:     extern value;
  определение:  value; или extern value =0;

и определение включает в себя объявление, но не наоборот.. 







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


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



Цитата

не верю что нельзя определить переменную в хидере 

ну и маленькое замечание, в данном контексте не объявление, а определение
  объявление:     extern value;
  определение:  value; или extern value =0;

Добро

Это сообщение отредактировал(а) t_gran - 22.2.2012, 18:09


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
efpies
Дата 23.2.2012, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(t_gran @  22.2.2012,  13:59 Найти цитируемый пост)
Не подумайте, что придираюсь, но тогда и delete к делу не относится.

ну да, Вы правы, но с десятью другими было бы все 11 smile


Цитата(mes @  22.2.2012,  12:31 Найти цитируемый пост)
расходится в чем ? 

Цитата(RSDN)

Допустим, у нас есть два модуля A.cpp и B.cpp. В модуле A определена целая переменная i вне всех классов и функций:
int i = 2;

Такая переменная называется глобальной. В файле A она видна от точки определения и до конца файла. Однако в модуле B эта переменная не видна. И если вдруг нам потребуется в модуле B присвоить ей другое значение, у нас возникнут некоторые проблемы. Нельзя просто написать:
i = 1;

В этом случае компилятор при обработке модуля B «не видит» модуль A и ничего не знает об определенной там переменной, поэтому мы получим сообщение о неопределенной переменной. Также нельзя написать:
int i = 1;

Такая запись является повторным определением. Потому модуле B надо объявить переменную следующим образом:
extern int i;

После этого можно использовать переменную i в файле B любым разрешенным способом.


Экстраполируя на мою задачу, A = constants.h, а B = Unit1.cpp. Я это понял так, раз объявляю её в A, а использовать хочу в B.
PM MAIL   Вверх
mes
Дата 23.2.2012, 01:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(efpies @  22.2.2012,  23:01 Найти цитируемый пост)
 у нас есть два модуля A.cpp и B.cpp

Цитата(efpies @  22.2.2012,  23:01 Найти цитируемый пост)
Экстраполируя на мою задачу,

модуль это не отдельный файл, а грубо .cpp со всеми включенными хидерами... 

и если быть точнее, не модуль, а единица трансляции..



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


Новичок



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

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



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

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

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

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

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


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

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


 




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


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

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