在interface.h中定义strInterface
// interface.h
#ifndef INTERFACE_H_
#define INTERFACE_H_
const char* strInterface = "the difference between char* and char array";
#endif
调用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;
}
包含了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
关键字声明全局变量,并在某人的实现文件中定义它。
答案 0 :(得分:2)
不同之处在于const char strInterface[]
定义了一个常量。常量对于它们包含的每个文件都是本地的。您将在每个文件中获得一个单独的副本。
指针const char* strInterface
指向常量数据,但指针本身不是常量。因此,默认情况下,其他翻译单元可以看到它。
答案 1 :(得分:1)
声明为const
的命名空间范围变量默认情况下具有内部链接,因此您可以在多个翻译单元中定义具有相同名称的变量,而不会导致链接错误。
此变量不是const
,因此它将具有外部链接,这意味着任何程序中只能存在一个此类定义:
const char* strInterface = "...";
const
版本将是:
const char* const strInterface = "...";
这是const
,因为数组的constness与其元素的constness没有区别。 (IIRC在标准中对这一事实有一些正式的含糊不清。)你可以在一个程序中为每个翻译单元设置一个这样的定义。
const char strInterface[] = "...";
答案 2 :(得分:1)
这里有两种不同的类型:
首先,const char* strInterface
是一个指向常量字符的指针,因此您在两个不同的编译单元中创建一个在全局范围内具有相同名称的指针,使链接器抱怨它。请注意,您可以使指针指向代码中稍后完全不同的内容。指针本身是可变的;它指向的字符串是不可变的。
其次,const char strInterface[]
是一个常量字符数组,它是为每个编译单元本地创建的,因此链接器会找到该字符串的多个不会发生冲突的定义。这个常数是不可变的。