In A.h:
#ifndef A_h
#define A_h
#include "string"
extern std::string a;
#endif
In A.cpp, in the global scope:
#include "A.h"
std::string a = "a";
In A.h:
#ifndef A_h
#define A_h
#include "string"
extern std::string a;
#endif
In A.cpp, in the global scope:
#include "A.h"
std::string a = "a";
You are not redefining a variable, because your code has only one definition - the one in the CPP file. The one in the header is a declaration, because it uses an extern keyword. The CPP file provides a definition to the variable declared in the header.
Think of it this way: The compiler sees A.cpp once, and only once. If your project has many source files that #included A.h, the compiler would see A.h multiple times, once for each #include, as it processes all the *.cpp files. It is logical in that scenario that there be one definition, and multiple declarations
What you have is correct - a variable in global scope in A.cpp. Being global and non-static, it has the potential to be used elsewhere. In fact it is polluting the namespace if it is not used elsewhere.