1
  • определяют strInterface в interface.hПочему существуют различия между char * и char [] в случае множественного определения?

    // interface.h 
    #ifndef INTERFACE_H_ 
    #define INTERFACE_H_ 
    const char* strInterface = "the difference between char* and char array"; 
    #endif 
    
  • в классе OneUsing, strInterface строка называется

    // oneUsingInterface.h 
    #ifndef ONEUSINGINTERFACE_H_ 
    #define ONEUSINGINTERFACE_H_ 
    
    class OneUsing 
    { 
    private: 
        int mData; 
    public: 
        OneUsing(); 
        OneUsing(int a); 
        void print(); 
    }; 
    #endif // ONEUSINGINTERFACE_H_ 
    
    // oneUsingInterface.cpp 
    #include "oneUsingInterface.h" 
    #include "interface.h" 
    #include <iostream> 
    
    using namespace std; 
    
    OneUsing::OneUsing() 
    {} 
    OneUsing::OneUsing(int a) 
    { 
        mData = a; 
    } 
    void OneUsing::print() 
    { 
        cout<<"mData: "<<mData<<" strInterface: "<<strInterface<<endl; 
    
    } 
    
  • в main.cpp, interface.h входит в strInterface является вызываемый непосредственно; он также включает oneUsingInterface.h, поскольку экземпляр OneUsing будет создан.

    //main.cpp 
    #include <iostream> 
    #include "interface.h" 
    #include "oneUsingInterface.h" 
    
    using namespace std; 
    
    int main() 
    { 
        cout<<strInterface<<endl; 
        OneUsing* pObject = new OneUsing(5); 
        pObject->print(); 
    } 
    
  • Теперь вопрос, возникающий:

    g++ -I../boost_1_52_0/installation/prefix/include -I../boost_1_52_0/installation/prefix/lib -g -Wall -Wextra -c .//main.cpp 
    g++ -I../boost_1_52_0/installation/prefix/include -I../boost_1_52_0/installation/prefix/lib -g -Wall -Wextra -c .//oneUsingInterface.cpp 
    g++ -I../boost_1_52_0/installation/prefix/include -I../boost_1_52_0/installation/prefix/lib -g -Wall -Wextra main.o oneUsingInterface.o -o main 
    oneUsingInterface.o:(.data+0x0): multiple definition of `strInterface' 
    main.o:(.data+0x0): first defined here 
    collect2: error: ld returned 1 exit status 
    make: *** [main] Error 1 
    
  • Однако, если strInterface определяется как это, нет никаких проблем, то:

    // interface.h 
    #ifndef INTERFACE_H_ 
    #define INTERFACE_H_ 
    const char strInterface[] = "the difference between char* and char array"; 
    #endif 
    

Могут ли некоторые ребята расскажите подробнее о разнице между char* и char[] в этом случае?

PS: мы часто объявляем глобальную переменную с ключевым словом extern в файле заголовка, и мы определяем ее в чей-то файл реализации.

ответ

2

Разница в том, что const char strInterface[] определяет константу. Константы являются локальными для каждого файла, в который они включены. В каждом файле вы получите отдельную копию.

Указатель const char* strInterface указывает на постоянные данные, но сам указатель не является константой. Таким образом, по умолчанию он отображается для других единиц перевода.

1

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

Эта переменная не const, поэтому он будет иметь внешних связей что означает, что только одно такое определение может существовать в любой программе:

const char* strInterface = "..."; 

версия const будет:

const char* const strInterface = "..."; 

Это const, потому что нет никакого различия между константой массива и константой его элементов. (IIRC существует некоторая формальная двусмысленность об этом факте в стандарте.) У вас может быть одно такое определение для единицы перевода в программе.

const char strInterface[] = "..."; 
1

У вас есть два различных типа здесь:

во-первых, const char* strInterface является указателем на постоянный характер, и, следовательно, вы создаете указатель того же имени в глобальном масштабе в двух различных единицах компиляции решений компоновщик жалуется на это.Обратите внимание, что вы можете сделать указатель на что-то совершенно другое в коде. Сам указатель изменчив; строка, на которую указывает, является неизменной.

Во-вторых, const char strInterface[] - это массив постоянных символов, который создается локально для каждого блока компиляции, поэтому компоновщик находит несколько определений этой строки, которые не сталкиваются. Эта константа неизменна.