Я читаю "Поміркуй на C ++", і він просто представив externдекларацію. Наприклад:
extern int x;
extern float y;
Я думаю, що я розумію значення (декларація без визначення), але мені цікаво, коли це виявиться корисним.
Хтось може навести приклад?
Я читаю "Поміркуй на C ++", і він просто представив externдекларацію. Наприклад:
extern int x;
extern float y;
Я думаю, що я розумію значення (декларація без визначення), але мені цікаво, коли це виявиться корисним.
Хтось може навести приклад?
Відповіді:
Це корисно, коли у вас є глобальні змінні. Ви заявляєте про існування глобальних змінних у заголовку, так що кожен вихідний файл, що включає заголовок, знає про нього, але вам потрібно лише "визначити" його один раз в одному з вихідних файлів.
Для уточнення, використовуючи extern int x;підказує компілятору, що об'єкт типу, що intназивається, xіснує десь . Це не робота компіляторів, щоб знати, де вона існує, вона просто повинна знати тип та назву, щоб вона знала, як ними користуватися. Після того, як всі вихідні файли будуть скомпільовані, лінкер вирішить усі посилання xна одне визначення, яке він знайде в одному з компільованих вихідних файлів. Щоб вона працювала, визначення xзмінної повинно мати те, що називається "зовнішня зв'язок", що в основному означає, що її потрібно оголосити поза функцією (у тому, що зазвичай називають "область файлу") і без staticключового слова.
#ifndef HEADER_H
#define HEADER_H
// any source file that includes this will be able to use "global_x"
extern int global_x;
void print_global_x();
#endif
#include "header.h"
// since global_x still needs to be defined somewhere,
// we define it (for example) in this source file
int global_x;
int main()
{
//set global_x here:
global_x = 5;
print_global_x();
}
#include <iostream>
#include "header.h"
void print_global_x()
{
//print global_x here:
std::cout << global_x << std::endl;
}
Це корисно, коли ви поділяєте змінну між декількома модулями. Ви визначаєте його в одному модулі, а в інших використовуєте зовнішній.
Наприклад:
у file1.cpp:
int global_int = 1;
у file2.cpp:
extern int global_int;
//in some function
cout << "global_int = " << global_int;
global_intє у глобальній просторі імен, якби я використовував його у file2.cpp в якомусь розділі простору імен, я повинен був би це обґрунтувати правильно? тобтоnamespace XYZ{ void foo(){ ::global_int++ } };
abc.h, є хороший шанс, що вона буде визначена в abc.cpp. Хороший IDE завжди допоможе, але добре організований код - це завжди краще рішення.
externфайлу2.cpp, все ще може отримати доступ до global_intпісля включення. чому мені це потрібно?
Вся справа в зв'язках .
Попередні відповіді дали хороші пояснення щодо extern.
Але я хочу додати важливий момент.
Ви питаєте про externв С ++ не в C , і я не знаю , чому немає відповіді згадувати про той випадок , коли externприходить з constв C ++.
У C ++ constзмінна має внутрішню зв'язок за замовчуванням (не як C).
Тож цей сценарій призведе до помилки зв’язку :
Джерело 1:
const int global = 255; //wrong way to make a definition of global const variable in C++
Джерело 2:
extern const int global; //declaration
Це має бути таким:
Джерело 1:
extern const int global = 255; //a definition of global const variable in C++
Джерело 2:
extern const int global; //declaration
externвизначення? Ви можете зробити це, роздрукувавши значення globalв джерелі 2.
externвона опущена const int global = 255;.
Це корисно, коли ви хочете мати глобальну змінну. Ви визначаєте глобальні змінні в якомусь вихідному файлі і оголошуєте їх зовнішніми у файлі заголовка, щоб будь-який файл, що включає цей заголовок, побачив ту саму глобальну змінну.
externкілька разів. Інструменти Microsoft створили помилку посилання для відсутніх символів, коли таблиці в іншому вихідному файлі були лише визначені. Проблема полягала в тому, що таблиця була,constі компілятор C ++ просував їїstaticв блок перекладу. Дивіться, наприклад,ariatab.cppіkalynatab.cpp.