Какие связи предоставляются нелокальным переменным-членам в c ++? - PullRequest
0 голосов
/ 26 марта 2020

Я предполагаю, что у членов данных класса есть связь (или нет связи), как показано ниже
Это правильно?

class AAA {
public:                          // this doesn't matter

  int var1;                      // no linkage
  const int var2 = 0;            // no linkage

  static int var3;               // external linkage (declaration)
  static const int var4 = 0;     // external linkage (declaration + definition)

};

int AAA::var3 = 0; // external linkage (definition)

1 Ответ

0 голосов
/ 13 апреля 2020

Прежде всего я задал вопрос о том, какие связи предоставляются членам данных
, и мое предположение было правильным, и ММ ответил, что все в порядке.
Я дважды проверил в стандарте и да, связи верны, как я и ММ сказали выше

Но, как упомянул ММ, я неправильно понял, какое из них является объявлением или определением
Это немного не так, как надо c, но я отвечаю сам за того, кто будет читать это в будущем

[1] если речь идет о нештатном c элементе данных

struct A {
  int var1;        // definition (initial value is 0)
  int var2 = 100;  // definition (initial value is 100)
};

[2] если речь идет о stati c const

struct A {
  static const int var1 = 100; // declaration (initial value is 100)
  static const int var2;       // declaration (initial value is 0)
};

const int A::var1;             // definition (an option for odr-used situation)
const int A::var2 = 10;        // definition

[3] если он доходит до состояния c constexpr

constexpr члены данных интересны и работают по-разному
, поскольку из C ++ 17 элемент данных с constexpr подразумевает inline
и inline фактически определяют его

плюс каждый inline член данных в каждой единице перевода гарантированно имеет одно и то же определение
(https://eel.is/c++draft/depr.static.constexpr)

struct A {
  static constexpr int n = 5;   // definition (declaration in C++ 2014)
};

constexpr int A::n;             // redundant declaration (definition in C++ 2014)

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

// foo.cpp
#include <iostream>

class AAA {
public:
    static constexpr int var = 10; 
};

void foo() {
    std::cout << &AAA::var << std::endl;
}

// main.cpp
#include <iostream>

class AAA {
public:
    static constexpr int var = 10; 
};

void foo();

int main() {
    std::cout << &AAA::var << std::endl;
    foo();
}

и результат как ниже

$ g++ -std=c++17 main.cpp foo.cpp
$ ./a.out 
0x564ba82a3a54
0x564ba82a3a54
...