1
  • interface.h で strInterface を定義する

    // 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 では、strInterface が直接呼び出されるため、interface.h が含まれます。OneUsing インスタンスが作成されるため、oneUsingInterface.h も含まれます。

    //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、誰かの実装ファイルで定義することがよくあります。

4

3 に答える 3

2

違いはconst char strInterface[]、定数を定義することです。定数は、それらが含まれている各ファイルにローカルです。各ファイルに個別のコピーを取得します。

ポインターconst char* strInterfaceは定数データを指していますが、ポインター自体は定数ではありません。したがって、デフォルトでは、他の翻訳単位に表示されます。

于 2013-04-22T09:21:26.180 に答える
1

const宣言された名前空間スコープの変数には、デフォルトで内部リンケージがあるため、リンク エラーを引き起こすことなく、複数の翻訳単位で同じ名前の変数を定義できます。

この変数は ではないため、外部リンケージconstを持つことになります。これは、このような定義が 1 つのみプログラムに存在できることを意味します。

const char* strInterface = "...";

constバージョンは次のようになります。

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

これはconst、配列の const 性とその要素の const 性の間に区別がないためです。(IIRC の標準では、この事実について正式なあいまいさがあります。) プログラム内の翻訳単位ごとに、そのような定義を 1 つ持つことができます。

const char strInterface[] = "...";
于 2013-04-22T09:21:27.840 に答える