Если вам нужны глобальные переменные, обычная практика - объявлять их в файле .h и определять их в одном (и только одном) файле .cpp.
В файле .h;
extern int x;
В файле .cpp;
int x=3;
Я использовал int (возможно, самый базовый базовый тип?), А не const char *, как в вашем примере, потому что суть вашей проблемы не зависит от типа переменной.
Основная идея заключается в том, что вы можете объявлять переменную несколько раз, поэтому каждый файл .cpp, содержащий файл .h, объявляет переменную, и это нормально. Но вы определяете это только один раз. Определение - это оператор, в котором вы назначаете начальное значение переменной (с =). Вам не нужны определения в файлах .h, потому что тогда, если файл .h включен в несколько файлов .cpp, вы получите несколько определений. Если у вас есть несколько определений одной переменной, во время компоновки возникает проблема, поскольку компоновщик хочет назначить адрес переменной и не может разумно сделать это, если существует несколько ее копий.
Дополнительная информация добавлена позже, чтобы попытаться облегчить путаницу Суда;
Постарайтесь свести свою проблему к ее минимальным частям, чтобы лучше ее понять;
Представьте, что у вас есть программа, которая содержит три файла .cpp. Для сборки программы каждый .cpp компилируется отдельно для создания трех объектных файлов, затем три объектных файла связываются вместе. Если три файла .cpp следующие (пример A, хорошая организация);
file1.cpp
extern int x;
file2.cpp
extern int x;
file3.cpp
extern int x;
Затем файлы будут скомпилированы и скомпонованы без проблем (по крайней мере, в отношении переменной x). Нет проблем, потому что каждый файл объявляет только переменную x. Объявление просто указывает, что где-то есть переменная, которую я могу (или не могу) использовать.
Лучший способ добиться того же - следующий (пример А, лучшая организация);
header.h
extern int x;
file1.cpp
#include "header.h"
file2.cpp
#include "header.h"
file3.cpp
#include "header.h"
Это практически одно и то же: для каждой из трех компиляций компилятор видит тот же текст, что и раньше, когда обрабатывает файл .cpp (или модуль перевода, как его называют эксперты), потому что директива #include просто извлекает текст из другого файла. Тем не менее, это улучшение по сравнению с предыдущим примером просто потому, что у нас есть только наше объявление в одном файле, а не в нескольких файлах.
Теперь рассмотрим другой рабочий пример (пример B, хорошая организация);
* * File1.cpp тысяча сорок-девять
extern int x;
file2.cpp
extern int x;
file3.cpp
extern int x;
int x=3;
Это тоже будет хорошо работать. Все три файла .cpp объявляют x и один фактически определяет его. Мы могли бы пойти дальше и добавить больше кода в функции в любой из трех файлов, которые манипулируют с переменной x, и мы не получили бы никаких ошибок. Опять же, мы должны использовать заголовочный файл, чтобы объявление входило только в один физический файл (пример B, лучшая организация).
header.h
extern int x;
file1.cpp
#include "header.h"
file2.cpp
* * 1068
file3.cpp
#include "header.h"
int x=3;
Наконец, рассмотрим пример, который просто не будет работать (пример C, не работает);
file1.cpp
int x=3;
file2.cpp
int x=3;
file3.cpp
int x=3;
Каждый файл будет компилироваться без проблем. Проблема возникает во время соединения, потому что теперь у нас есть определенные три отдельные переменные int x. Они имеют одно и то же имя и являются глобально видимыми. Задача компоновщика - собрать все объекты, необходимые для одной программы, в один исполняемый файл. Глобально видимые объекты должны иметь уникальное имя, чтобы компоновщик мог поместить одну копию объекта по одному определенному адресу (месту) в исполняемом файле и разрешить всем другим объектам доступ к нему по этому адресу. В этом случае компоновщик не может выполнять свою работу с глобальной переменной x, поэтому вместо этого он заблокирует ошибку.
Кроме того, если дать разные определения, различные начальные значения не решают проблему. Предшествующее каждому определению с ключевым словом static решает проблему, потому что теперь переменные не видны глобально, а скорее видны в файле .cpp, в котором они определены.
Если вы поместите определение глобальной переменной в файл заголовка, ничего существенного не изменится (пример C, организация заголовка в этом случае не поможет);
header.h
int x=3; // Don't put this in a .h file, causes multiple definition link error
file1.cpp
#include "header.h"
file2.cpp
#include "header.h"
file3.cpp
#include "header.h"
Фу, я надеюсь, что кто-то прочитает это и получит некоторую пользу от этого. Иногда спрашивающий просит простое объяснение в терминах основных понятий, а не объяснение продвинутого ученого.