Чому const передбачає внутрішній зв’язок у C ++, а в C - ні?


83

Див. Тему. Що вони думали?

ОНОВЛЕННЯ: змінено зі "статичного" на "внутрішній зв'язок", щоб зберегти плутанину

Для прикладу ... Поміщення у файл наступного:

const int var_a = 1;
int var_b = 1;

... і складаючи g++ -c test.cppлише експорт var_b.

Відповіді:


113

Я вірю, ви маєте на увазі

Чому const передбачає внутрішній зв'язок у C ++

Це правда, що якщо ви оголосите об'єкт const в області простору імен, то він має внутрішній зв'язок.

Додаток С ( С ++ 11, С.1.2 ) дає обґрунтування

Зміна: Назва області файлу, яка явно оголошена const, а не явно оголошена extern, має внутрішню зв'язок, тоді як у C вона матиме зовнішню зв'язок

Обґрунтування: Оскільки об’єкти const можуть використовуватися як значення часу компіляції в C ++, ця функція закликає програмістів надати явні значення ініціалізатора для кожної const. Ця функція дозволяє користувачеві розміщувати об'єкти const у файлах заголовків, які входять до багатьох одиниць компіляції.


Здається, глобальні об'єкти, що не є const, також можна ініціалізувати, але чому стандарт не дає йому внутрішнього зв'язку?
Yong Li

13

Як сказав Litb, constоб'єкти мають внутрішню зв'язок у C ++. Це тому, що вони призначені для використання таким чином:

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];

6

Const і static - це ортогональні поняття як на C, так і на C ++.

constКлючове слово вказує компілятору , щоб заборонити змінну з'являтися як Lvalue будь-якого виразу - по суті , робить його тільки для читання.

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

У C ++ staticключове слово може використовуватися у визначенні класу для створення змінної або функцій, спільних для всіх екземплярів класу, а не для кожного з них. Крім того, статична функція класу в C ++ може отримувати доступ лише до статичних змінних цього класу (або класів, до яких вона має доступ). Тепер у C ++ constнадає членам внутрішній зв'язок з блоком компіляції, якщо вони явно не оголошені extern- це може бути те, що ви посилаєтесь на нього. Це дозволяє спільно використовувати константи часу компіляції між блоками за допомогою файлів заголовків. Однак майте на увазі, що члени насправді не є статичними - скоріше константа компілюється в кожному розташуванні, де на неї посилаються.


6

У C & C ++ термін static має декілька значень (він може регулювати зв'язок та зберігання). Вам доведеться прочитати D&E Stroustrup, щоб оцінити його обгрунтування - але коли ви оголошуєте змінну const у просторі імен, вона автоматично має внутрішню зв'язок - тоді як в C ви повинні оголосити його статичним, щоб змусити його мати внутрішній зв'язок.

Звичайно, в C ++ застаріле використання static для управління зв’язками, анонімні простори імен можуть використовуватися для імітації внутрішнього зв’язку в C ++.

змінні const у C ++ повинні були замінити константи препроцесора - і оскільки константи препроцесора видно лише у файлах, які їх визначають, аналогічним чином, const автоматично робить змінну видимою лише у файлі, який її визначає.


4

Ці поняття є ортогональними і не повинні сприйматися як одне і те ж.

Constness - це властивість доступу: вона повідомляє лише про те, якщо ваша змінна повинна бути лише для читання (const) або для читання із записом (non-const).

Статичність - це властивість життя (і технічно локалізація пам'яті): вона повідомляє, чи буде змінна глобальною в області дії класу (коли вона в класі) або одиниці перекладу (коли використовується з глобальною змінною, визначеною в cpp) .


-2

Це не так, і найбільш очевидним прикладом є те, що якщо у вас є змінна-член const (яка ініціалізується конструктором, звичайно), вона не буде спільною для всіх об’єктів цього класу, але індивідуальна для кожного.

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

litb дає найкращу відповідь вище.


Чи не завжди? (litb)
RastaJedi

-5

Це не так. Написання наступного:

const int i = 0;

не робить iстатичним (ні на С, ні на С ++).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.