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

  • определить strInterface в interface.h

    // 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 Ключевое слово в заголовочном файле, и мы определяем его в чьем-то файле реализации.

1

Решение

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

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

2

Другие решения

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

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

const char* strInterface = "...";

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

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

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

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

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

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

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

1
По вопросам рекламы [email protected]