class Student {
public:
string name;
};
VS
class Student {
public:
char* name;
};
如果我错了,请纠正我。如果我们使用char *而不是string,我们将不得不编写自己的copy-constructor,因为每次我们都需要将指针变量作为数据成员。对?
所以,我的问题是:为什么要使用char *?
使用string,在构造函数中,我们可以直接执行:
Student(string s) {
name = s;
}
与char *相比更简单,需要:
Student(string s) {
name = new char[strlen(s)+1]; // extra 1 to store the '\n'
strcpy(name,s);
}
当用作类的数据成员时,为什么不一直使用字符串而不是char *?
答案 0 :(得分:2)
我认为{C}中使用char*
作为字符串的唯一原因是因为C.我确定它是否是一种新语言,并不努力与之兼容C,char*
不会像那样使用。您会注意到处理char*
的函数就好像它是一个字符串都来自C。
请注意,在C中,没有字符串,所以
struct Student { char* name; };
是完全有效的C代码,而
struct Student { string name; };
不是。因此,在处理以前以C为目标的代码时,查看那些char*
类型并不罕见。
除非您要么编写新的字符串类,连接C函数或处理遗留代码,否则通常没有理由将char*
用作字符串。
答案 1 :(得分:2)
您使用char *
代替string
,因为string
是字符串而char *
是指向字符对齐地址的指针。
扩展,字符串是具有已定义语义的字符向量的抽象。在C land和许多C ++程序中,它表示一个已分配的内存块,并保证它以ascii NUL字符0x00
终止。但是,字符串的C ++实现可以改为使用具有相关长度的Pascal字符串,或者它可以将字符串池中的字符串表示为链接列表。
char *
根本没有提供这种保证,实际上不可能是一个字符串 - 例如,它可能是嵌入了{{1}的数据集合值。所有它承诺的是它是底层架构认为是一个角色的地址。
答案 2 :(得分:0)
如果您需要字符串,请使用std::string
,而不是char*
。
一个明显的例外是与使用char*
表示字符串的遗留代码连接。但是,不要在界面层之外使用char*
。
当您的数据不是字符串,而是原始的非结构化字节数组时,您需要使用char*
。当您从文件或网络接口读取或写入二进制数据时就是这种情况。
答案 3 :(得分:0)
有时候,使用char*
而不是string
更简单,例如,当您处理网络时,需要将一个字符串变换为整数,浮点数等。我认为使用char*
而不是string
更简单:
char*
char* buffer[4];
read(buffer, 4); // A random read operation
int value = *((int*)(&buffer[0]); // Not sure if it was like that...
string
std::string buffer;
buffer.resize(4);
read(buffer.data(), 4); // Will not work as buffer.data() returns a const char*
int value = *((int*)(&buffer.data()[0]));
string
的问题在于它旨在防止错误使用或奇怪的操作。正如有人所说,这也是因为C ++是从C继承的。所以有一些函数(来自libc / glibc)需要char*
而不是string
。
即使char*
与char**
不同,使用std::vector
或std::string
构建二维数组也非常复杂,您应该选择合适的类,使用char**
或库特定的实现(Boost,Maths libs等)
答案 4 :(得分:0)
关于唯一一个有能力的C ++程序员将使用char*
的地方是extern "C"
程序的界面,或者是非常低级的代码,如malloc
的实现(其中你需要向void*
添加一些字节。即使在调用C ABI时,接口所需的char*
通常来自&s[0]
,其中s
是std::string
,或者接口不是const意识到(并且很多C接口不是),然后是const_cast
。
char const*
有点频繁:毕竟,字符串文字是char const[]
,我偶尔会定义类似的内容:
struct S
{
int value;
char const* name;
};
但仅限于静态数据,例如:
S const table[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
这可以用来避免初始化问题的顺序;在上面,初始化是静态的,并保证在任何动态初始化之前发生。
还有其他几种情况:例如,当我在C ABI之间进行编组时,我使用了char const*
。但它们很少见。