1 Востаннє редагувалося Betterthanyou (02.11.2015 21:03:48)

Тема: Клас пам'яті extern, оголошення зміної

Я не розумію як правильно оголошувати зміну класу пам'яті extern

файл Source.cpp

#include <conio.h>
#include <iostream>
#include "Header.h"

int main()
{

    f();

    std::cout << num;

    num = 6;

    std::cout << num;

    getch();
    return 0;
}

файл Source1.cpp

#include "Header.h"

int num;

void f()
{
    num = 8;
}

файл Header.h

#pragma once

extern int num;

void f();

extern - зовнішня (глобальна) змінна. Зовнішні змінні доступні скрізь, де описані, а не тільки там, де визначені. Включення ключового слова extern дозволяє функції використовувати зовнішню змінну, навіть якщо вона визначається пізніше в цьому або іншому файлі.

я написав extern int num; тобто оголосив її глобальною для всіх файлів

то навіщо мені ще раз її оголошувати в Source1.cpp як звичайну зміну а в Source.cpp не оголошувати, звідки мені дізнатися де її потрібно повторно оголосити а де ні ?

2 Востаннє редагувалося koala (02.11.2015 21:13:03)

Re: Клас пам'яті extern, оголошення зміної

Навпаки: там, де маєте глобальну змінну, можете отримати доступ до неї за допомогою extern, якщо тільки вона не static:
Source1.cpp:

...
int num;
...

Source.cpp:

...
extern int num;//в цьому коді не виділяється пам'ять, а виставляється мітка, що в якомусь іншому файлі є глобальна змінна num, і лінкувальник її прив'яже до цієї змінної
...

Звісно, якщо розмістити проголошення extern в .h-файлі, то змінна стане доступною з усіх файлів, що використовують цей хедер.

Ну і глобальні змінні - зло, ви ж в курсі?

Подякували: Arete, Betterthanyou, leofun013

3

Re: Клас пам'яті extern, оголошення зміної

І якщо звернути увагу на термінологію то немає такого класу пам’яті як extern. Extern  визначає зовнішню лінковку, а не клас пам’яті.

life is too short to remove usb safely
Подякували: koala, coder, Yola3

4

Re: Клас пам'яті extern, оголошення зміної

koala написав:

Ну і глобальні змінні - зло, ви ж в курсі?

Так, алей я не знаю як від неї відмовитися

в мене є дві форми з якими буде працювати користувач в них (формах) є
Unit1.cpp
Unit1.h
Unit2.cpp
Unit2.h

для захисту даних є таймер який через деякий час не активності закриває форму з якою працював користувач і включає форму три

( а в третій
Unit3.cpp
Unit3.h
)

третя форма служить авторизацією і коли користувач авторизується вона має закритися і включити ту форму яку закрив таймер

коли таймер спрацьовує потрібно запам'ятати яка форма закрилась. От я і не знаю як запам'ятати яка форма закрилась том я використовую такий код

таймер форми1()
{

закрити цю форму;
відкрити форму авторизації;

Глобальна_зміна = 1;

}

таймер форми2()
{

закрити цю форму;
відкрити форму авторизації;

Глобальна_зміна = 2;

}

і для форми авторизації

if(пароль_і_логін_правельні)
{

if(Глобальна_зміна==1)
{
відкрити форму 1;
}
else
if(Глобальна_зміна==2)
{
відкрити форму 2;
}


}

Я працюю в Builder C++

5

Re: Клас пам'яті extern, оголошення зміної

Arete написав:

І якщо звернути увагу на термінологію то немає такого класу пам’яті як extern. Extern  визначає зовнішню лінковку, а не клас пам’яті.

це я прочитав в Вікіпедії
https://ru.wikipedia.org/wiki/Класс_памяти

6 Востаннє редагувалося Itari (02.11.2015 22:33:07)

Re: Клас пам'яті extern, оголошення зміної

Навiщо закривати та запам'ятовувати форми, коли можна форму авторизацii показувати модально? Через ShowModal().
Якщо авторизация повторно не пройде - просто вирубати ExitProcess()-ом все ПО и дзуськи.

Подякували: Betterthanyou, koala2

7 Востаннє редагувалося koala (02.11.2015 22:42:53)

Re: Клас пам'яті extern, оголошення зміної

А в формі авторизації додати змінну formToReturn і встановлювати її не пробували?
Хоча рішення з модальним вікном краще. Ховаєте форму, викликаєте третю форму модальною і в тій самій функції таймера показуєте форму назад.

8

Re: Клас пам'яті extern, оголошення зміної

Betterthanyou написав:
Arete написав:

І якщо звернути увагу на термінологію то немає такого класу пам’яті як extern. Extern  визначає зовнішню лінковку, а не клас пам’яті.

це я прочитав в Вікіпедії
https://ru.wikipedia.org/wiki/Класс_памяти

Несподівана стаття, чув що на вікіпедії бувають лажові статті, але до цього часу не зустрічав :) Не читайте її, вона шкідлива )) В стандарті я нічого не знайшов по типу "memory class extern". Скоріш за все дві дамочки в своїй книзі щось собі нафантазували, не розібравшись в темі, а хтось вирішив з цього написати статтю.

Про зберігання змінних та лінковку ось тут добре розписано.
http://en.cppreference.com/w/cpp/langua … e_duration

З.І. Для пошуку інформації по плюсам я часто користуюсь сайтами
http://en.cppreference.com
http://www.cplusplus.com
Хороші сайти, рекомендую.  Хоча і вікіпедія достовірне джерело  ©"це я вам як імператор Австрії кажу"  :D

life is too short to remove usb safely
Подякували: Betterthanyou, leofun012

9 Востаннє редагувалося coder (02.11.2015 23:28:20)

Re: Клас пам'яті extern, оголошення зміної

В С/C++ у змінних є ім'я, тип, лінкейдж, клас пам'яті, область видимості, лайфтайм i категорія даних (value category). Те що ви вказуєте через extern це задання лінкейджу, тобто параметра який вказує лінкеру як ідентифікатори (імена змінних в нашому випадку) можуть бути звязані, чи в межах усієї програми чи тільки в межах одного файлу.

Треба чітко відрізняти declaration і definition в контексті змінних. Ви можете декларувати змінну скільки завгодно і паралельно вказувати лінкейдж і тільки раз відбувається визначення (definition) тобто виділення памяті під сутність.

Хочу ще додати один важливий момент. Коли ми явно не задаємо extern лінкейдж то змінна автоматом отримує локальний лінкейдж і визначення (definition) відбувається одночасно з декларацією. Лише при extern ми можемо спокійно декларувати одну і туж змінну багато раз у різних файлах так як при використанні extern не відбувається перевизначення (one definition rule), в іншому випадку ми отримуємо просто локальну змінну.

I can tell, seen before, I know the way, I know the law
Can't believe, can't obey, Can't agree with all the things I hear you say
Подякували: Betterthanyou, leofun012

10

Re: Клас пам'яті extern, оголошення зміної

Arete написав:
Betterthanyou написав:
Arete написав:

І якщо звернути увагу на термінологію то немає такого класу пам’яті як extern. Extern  визначає зовнішню лінковку, а не клас пам’яті.

це я прочитав в Вікіпедії
https://ru.wikipedia.org/wiki/Класс_памяти

Несподівана стаття, чув що на вікіпедії бувають лажові статті, але до цього часу не зустрічав :) Не читайте її, вона шкідлива )) В стандарті я нічого не знайшов по типу "memory class extern". Скоріш за все дві дамочки в своїй книзі щось собі нафантазували, не розібравшись в темі, а хтось вирішив з цього написати статтю.

Про зберігання змінних та лінковку ось тут добре розписано.
http://en.cppreference.com/w/cpp/langua … e_duration

З.І. Для пошуку інформації по плюсам я часто користуюсь сайтами
http://en.cppreference.com
http://www.cplusplus.com
Хороші сайти, рекомендую.  Хоча і вікіпедія достовірне джерело  ©"це я вам як імператор Австрії кажу"  :D

є лише одне непрацююче джерело http://www.intuit.ru/department/pl/c/class/free/10/ із "ИНТУИТ" схоже вже вони зрозуміли помилку а з Вікіпедії не видалили цю статтю

11

Re: Клас пам'яті extern, оголошення зміної

Прихований текст

Betterthanyou написав:
Arete написав:
Betterthanyou написав:

це я прочитав в Вікіпедії
https://ru.wikipedia.org/wiki/Класс_памяти

Несподівана стаття, чув що на вікіпедії бувають лажові статті, але до цього часу не зустрічав :) Не читайте її, вона шкідлива )) В стандарті я нічого не знайшов по типу "memory class extern". Скоріш за все дві дамочки в своїй книзі щось собі нафантазували, не розібравшись в темі, а хтось вирішив з цього написати статтю.

Про зберігання змінних та лінковку ось тут добре розписано.
http://en.cppreference.com/w/cpp/langua … e_duration

З.І. Для пошуку інформації по плюсам я часто користуюсь сайтами
http://en.cppreference.com
http://www.cplusplus.com
Хороші сайти, рекомендую.  Хоча і вікіпедія достовірне джерело  ©"це я вам як імператор Австрії кажу"  :D

є лише одне непрацююче джерело http://www.intuit.ru/department/pl/c/class/free/10/ із "ИНТУИТ" схоже вже вони зрозуміли помилку а з Вікіпедії не видалили цю статтю

Так, гугління по ISBN 978-5-9556-0057-4 теж не дало результату.

life is too short to remove usb safely

12 Востаннє редагувалося Itari (02.11.2015 23:50:43)

Re: Клас пам'яті extern, оголошення зміної

koala написав:

Ховаєте форму, викликаєте третю форму модальною і в тій самій функції таймера показуєте форму назад.

Таймер - це костиль. В данному випадку треба щось накштал OnIdle використовувати. Наприклад як зрозумiти, що з ПО не работають, коли юзер просто читае щось з екрану? Креслення або схеми... Це вважати роботою?

I ховати нiчого не треба - модальна форма все одно не дасть виходу до других форм, поки не закриеться.

додати змінну formToReturn

Теж не треба, бо для цього використовуеться ModalResult, вертаючи результат роботи модальних форм.

13

Re: Клас пам'яті extern, оголошення зміної

Itari написав:
koala написав:

Ховаєте форму, викликаєте третю форму модальною і в тій самій функції таймера показуєте форму назад.

Таймер - це костиль. В данному випадку треба щось накштал OnIdle використовувати. Наприклад як зрозумiти, що з ПО не работають, коли юзер просто читае щось з екрану? Креслення або схеми... Це вважати роботою?

Якраз навпаки. OnIdle викликається, коли черга подій спустошується - а тут треба відстежити момент, коли людина відійшла, в цей момент ніякий OnIdle не викличеться. Тобто OnIdle може бути потрібен, але для того, щоб перезапустити таймер, і те - тільки якщо додаток не обробляє нічого в фоні. Інакше перезапускати таймер доведеться при русі мишки і натисканнях на клавіатурі.
Ну і особисто я, коли читаю, зазвичай рухаю мишкою. Не обов'язково, але часто.

Itari написав:

I ховати нiчого не треба - модальна форма все одно не дасть виходу до других форм, поки не закриеться.

Не дасть фокусу, так. А от переглянути їх - ще й як дасть.

Itari написав:

додати змінну formToReturn

Теж не треба, бо для цього використовуеться ModalResult, вертаючи результат роботи модальних форм.

Та ні ж, питання в тому, як повідомити формі 3, яка з форм її викликала, а не в тому, що вона поверне. Звісно, краще, щоб форма 3 взагалі не знала, хто її викликає, але якщо вже використовувати таку модель - то змінна має бути у формі, а не глобальною.

Подякували: leofun011

14

Re: Клас пам'яті extern, оголошення зміної

koala написав:

Та ні ж, питання в тому, як повідомити формі 3, яка з форм її викликала, а не в тому, що вона поверне. Звісно, краще, щоб форма 3 взагалі не знала, хто її викликає, але якщо вже використовувати таку модель - то змінна має бути у формі, а не глобальною.

я вже придумав як ще можна зробити, створивши покажчик типу TForm в класі форми

//---------------------------------------------------------------------------

#ifndef Unit3H
#define Unit3H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm3 : public TForm
{
__published:    // IDE-managed Components
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:        // User declarations
    __fastcall TForm3(TComponent* Owner);
    TForm *form;//покажчик 
};
//---------------------------------------------------------------------------
extern PACKAGE TForm3 *Form3;
//---------------------------------------------------------------------------
#endif

перша і друга форма

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form1->Hide();
Form3->Show();

Form3->form = Form1;

}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2->Hide();
Form3->Show();

Form3->form = Form2;

}

форма три

form->Show();
Form3->Hide();

тепер працює

15

Re: Клас пам'яті extern, оголошення зміної

Все одно погано, інкапсуляція порушується.

void TForm3::ShowMeInstead(TObject *Sender)
{
  TForm *form = dynamic_cast<TForm*>(Sender);
  if( !form ){
    return;
  }
  form->Hide();
  result = ShowModal();
  ...//перевірити результат - це вже залежить від ваших потреб
  ...//в обробнику відповідної функції зробіть ModalResult = що треба
  ...//http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Controls_TModalResult.html
  form->Show();
}

Ну і на події в формах повісьте обробником, відповідно, Form3->ShowMeInstead

А ще - не називайте форми Form1, Form2 і Form3.

Подякували: Arete, Betterthanyou2

16 Востаннє редагувалося coder (03.11.2015 20:20:31)

Re: Клас пам'яті extern, оголошення зміної

Arete написав:

З.І. Для пошуку інформації по плюсам я часто користуюсь сайтами
http://en.cppreference.com
http://www.cplusplus.com
Хороші сайти, рекомендую.  Хоча і вікіпедія достовірне джерело  ©"це я вам як імператор Австрії кажу"  :D

Хороші сайти, підтверджую, але для початківців надто складним буде http://en.cppreference.com
Це я кажу вам як князь Теребовельський

I can tell, seen before, I know the way, I know the law
Can't believe, can't obey, Can't agree with all the things I hear you say

17

Re: Клас пам'яті extern, оголошення зміної

треба відстежити момент, коли людина відійшла

Це не можливо фiзично. Гонитва за флогiстоном... Тем паче, що ОС сама може блокувати себе, якщо прозвести декiлька налагоджень. Тобто результат: Марна праця над костилякою.

Ну і особисто я, коли читаю, зазвичай рухаю мишкою. Не обов'язково, але часто.

Супер вирiшення... Як раз це ТС нехай в rеadme и пише.

А от переглянути їх - ще й як дасть.

Що з того? Чому не скрити "важливi" форми, коли активуеться модальна?

питання в тому, як повідомити формі 3, яка з форм її викликала

Незрозумiло навiщо. Який сенс? Ну повiдомив - що далi? Скрити форму? Чому не скривати перед ShowModal()?
Чому не пройти по Screen.Forms та не поскривати все?

Це я кажу вам як князь Теребовельський

До Builder цi сайти вiдношення мають мало. Краще тодi на embarcadero заглядати.

18

Re: Клас пам'яті extern, оголошення зміної

Пане Itari, а розкажіть детальніше про своє життя. От реально цікаво - ваш комп'ютер налаштований на роботу без засинання, телефон сам не блокується, а планшет не вимикає екран, якщо його певний час не чіпати? Чи ви думаєте, що це все реалізовано без таймерів?

19

Re: Клас пам'яті extern, оголошення зміної

Запитай ТС: Вiд чого або кого вiн робить такий захист свого ПЗ.
I чому не зробить це методами домена чибто безпеки самой ОС.
I найглавнiше питання: Який критерiй "простою" ПЗ?

20

Re: Клас пам'яті extern, оголошення зміної

Itari написав:

Запитай ТС: Вiд чого або кого вiн робить такий захист свого ПЗ.
I чому не зробить це методами домена чибто безпеки самой ОС.
I найглавнiше питання: Який критерiй "простою" ПЗ?

Я з вам, перепрошую, свіні не пас.
В світі бувають досить специфічні вимоги до ПЗ. Якщо програміст каже, що йому треба - то, мабуть, дійсно треба саме це, хіба ні?
Ну а критерій - той самий, що й в автора: певний час без певних подій.