Могу ли я включить глобальный статический член? - PullRequest
2 голосов
/ 14 августа 2011

В одном из заголовочных файлов есть несколько глобальных переменных, которые являются статическими.Я вижу, что эти переменные используются в связанных .cc файлах.Итак, похоже, что это не имеет никаких проблем.

Мои вопросы:

  • В чем разница между включением глобальной переменной против статической глобальной переменной?Я знаю, что у static global нет видимости вне его файла.Но не знаю, как это будет работать, когда он входит в состав .h, который # включен.

  • Я написал пример программы и попробовал то же самое.Но я получаю ошибку компиляции в тот момент, когда я делаю переменную статической.Когда это просто глобально, это нормально.Итак, есть ли что-то, чего мне не хватает в обычной сборке g ++?(Обратите внимание, что первоначальный случай был в нашей официальной кодовой базе, в которой достаточно make-файлов, .h файлов и всего).

Спасибо за помощь!

Вотмой пример программы:

.h файл:

#include <iostream>

typedef unsigned int uint;

static const int appk=189;

class abc1
{
    public:
        abc1(int x);
        virtual void printVal();

};

.cc файл:

#include "abc1.h"

extern int appk;

abc1::abc1(int x)
{

}

void abc1::printVal()
{
    printf("abc1 print: %d\n", appk);
}

Ответы [ 3 ]

4 голосов
/ 14 августа 2011

(1) Если вы поместите глобальную переменную в файл .h и включите ее в различные файлы .cpp / .cc, то она будет определяться несколько раз для каждого файла.Так что вам больше всего нравится получать ошибку компоновщика .Чтобы преодолеть это, вы, скорее всего, будете использовать ключевое слово extern:

// myfile.h
extern int i;

и определять это только в одной единице перевода:

// somefile.cc
int i;

(2) Если вы поставите static global в .h файле и включите его, тогда вы не получите никакой ошибки, потому что для каждой другой единицы перевода будет другая копия для этой static глобальной переменной.

// myfile.h
static int i;  // creates a unique and unrelated copy in all .cc file where included

Однако такое использование устарело ;вместо этого лучше использовать неназванное namespace:

namespace {
  int i;
}

Из вашего вопроса я не вижу, что вы должны получить какую-либо ошибку компоновщика для static global.

2 голосов
/ 14 августа 2011

Трудно сказать вашу ошибку компиляции без кода, но если у вас есть заголовок, который объявляет статическую глобальную переменную, то вы просто создаете эту глобальную переменную независимо и отдельно в каждой единице перевода, которая включает заголовок.

Пример:

header.h:

#ifndef H_XXX
#define H_XXX

static int a;

#endif

file1.cpp:

#include "header.h"

// now have access to a variable called "a"

file2.cpp:

#include "header.h"

// now also have access to some "a"

Оба файла обаиметь доступ к глобальной переменной с именем a, но каждый файл имеет свою собственную отдельную копию, частную для своей единицы перевода, которая не видна снаружи.

Для практического примера я думаю, что объявлен coutкак статический глобал, поэтому каждый, кто использует <iostream>, получает свою собственную копию.

1 голос
/ 14 августа 2011

static переменная имеет внутреннюю связь. Это означает, что если у вас есть статическая переменная a в x.h и вы включаете x.h в два файла, скажем m.cpp и n.pp, то каждый из этих двух файлов получает свою собственную копию a, которая означает, что если вы измените его значение в m.cpp, то n.cpp не увидит этого изменения, поскольку в каждой единице перевода есть две переменные с одинаковым именем (.cpp). И они независимы друг от друга.

Но если a не является статичным, то, включив x.h в более чем один файл, вы получите ошибку множественного определения, потому что каждое включение x.h будет пытаться определить a, но с a не является статичным; теперь он имеет внешнюю связь, что означает, что если она определена в m.cpp, то вы получите ошибку при включении x.h в n.cpp (или наоборот). В этом случае вы должны написать x.h как:

//x.h
extern int a;

А затем определите a только в одном файле .cpp, либо m.cpp или n.cpp, но не в обоих. Скажите его m.cpp.

//m.cpp
#include "x.h"

int a =10;

И все готово. Теперь вы можете включить x.h в любое количество файлов .cpp и получить доступ к a, изменить его значение и делать все, что захотите. Любые изменения в нем будут теперь видны всем .cpp файлам.

...