为什么在多重定义的情况下char*和char[]之间存在差异
Why are there differences between char* and char[] in case of multiple definition?
-
在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
关键字声明全局变量,我们在某人的实现文件中定义它。
不同之处在于const char strInterface[]
定义了一个常量。常量是包含在每个文件中的本地常量。每个文件中都会有一个单独的副本。
指针const char* strInterface
指向常量数据,但指针本身不是常量。因此,默认情况下,它对其他翻译单元可见。
默认情况下,声明为const
的命名空间范围的变量具有内部链接,因此您可以在多个转换单元中定义具有相同名称的变量,而不会导致链接错误。
该变量不是const
,因此它将具有外部链接,这意味着在任何程序中只能存在一个这样的定义:
const char* strInterface = "...";
const
版本为:
const char* const strInterface = "...";
这是const
,因为数组的常量和元素的常量之间没有区别。(IIRC在标准中对这一事实有一些形式上的歧义。(在一个程序中,每个翻译单元可以有一个这样的定义。
const char strInterface[] = "...";
这里有两种不同的类型:
首先,const char* strInterface
是一个指向常量字符的指针,因此您在两个不同的编译单元中的全局作用域中创建了一个同名指针,这让链接器对此表示不满。请注意,您可以在代码的后面使指针指向完全不同的东西。指针本身是可变的;它指向的字符串是不可变的。
其次,const char strInterface[]
是一个常量字符数组,它是为每个编译单元本地创建的,因此链接器会找到该字符串的多个不冲突的定义。这个常数是不可变的。
- C++17:unique_ptr<char[]> 和 shared_ptr<char[] 之间的指针存储差异>
- char 和 char& 之间是否存在相对复制开销差异?
- 如果 strlen 在 char 数组之间遇到空格,它会怎么做
- void*和char*之间的差异
- "char *"和"char * = new char[]"之间的C++区别
- qsort()中的char*和char []之间的混淆
- (char*)和char*之间有什么区别
- C++ 中 int* 和 char* 之间的区别
- 函数调用中char[]和char*之间的差异
- 指针上的interpret_cast在char和unsigned char之间存在缺陷
- 我不能理解const char*和char*之间的区别
- 类和char *之间的强制转换
- char、char[]、char*之间的差异
- const void*到char之间的转换
- 在const wchar_t*和const char*之间进行转换,不允许使用qt
- char[]和char*之间的差异
- 为什么在多重定义的情况下char*和char[]之间存在差异
- char**和char*[]之间有什么区别
- "istream::get"和"operator>>(istream&, char&)"之间的区别
- ANSI代码页中wchar_t char之间的转换