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 中,包含 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在别人的实现文件中定义。

4

3 回答 3

2

不同之处在于它const char strInterface[]定义了一个常数。常量对于它们包含的每个文件都是本地的。您将在每个文件中获得单独的副本。

指针const char* strInterface指向常量数据,但指针本身不是常量。因此默认情况下,它对其他翻译单元可见。

于 2013-04-22T09:21:26.180 回答
1

You have two different types here:

First, const char* strInterface is a pointer to a constant character, and therefore you are creating a pointer of the same name in the global scope in two different compilation units making the linker complain about that. Note, that you could make the pointer point to something totally different later in the code. The pointer itself is mutable; the string it points to is immutable.

Second, const char strInterface[] is an array of constant characters, which is created locally for each compilation unit, therefore the linker finds multiple definitions of that string which don't clash. This constant is immutable.

于 2013-04-22T09:26:09.010 回答
1

默认情况下,声明的命名空间范围变量const具有内部链接,因此您可以在多个翻译单元中定义具有相同名称的此类变量而不会导致链接错误。

这个变量不是const,所以它会有外部链接,这意味着任何程序中只能存在一个这样的定义:

const char* strInterface = "...";

const版本将是:

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

这是const因为数组的 const 性与其元素的 const 性之间没有区别。(IIRC 在标准中对此事实存在一些形式上的歧义。)您可以在程序中的每个翻译单元有一个这样的定义。

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