string vs char *作为类成员变量。为什么要使用char *?

时间:2015-02-08 21:09:18

标签: c++

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 *?

5 个答案:

答案 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::vectorstd::string构建二维数组也非常复杂,您应该选择合适的类,使用char**或库特定的实现(Boost,Maths libs等)

答案 4 :(得分:0)

关于唯一一个有能力的C ++程序员将使用char*的地方是extern "C"程序的界面,或者是非常低级的代码,如malloc的实现(其中你需要向void*添加一些字节。即使在调用C ABI时,接口所需的char*通常来自&s[0],其中sstd::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*。但它们很少见。