C++ c++;构造函数中的char*初始化

C++ c++;构造函数中的char*初始化,c++,constructor,char,initialization,C++,Constructor,Char,Initialization,我只是好奇,我想知道这里发生了什么: class Test { char * name; public: Test(char * c) : name(c){} }; 1) 为什么Test(const char*c):name(c){}不起作用?因为char*name不是常量?但是这个呢: main(){ char * name = "Peter"; } name是char*,但是“Peter”是const char*,对吗?那么初始化是如何工作的呢 2) Test(char*c):name(

我只是好奇,我想知道这里发生了什么:

class Test
{
char * name;
public:
Test(char * c) : name(c){}
};
1) 为什么
Test(const char*c):name(c){}
不起作用?因为
char*name
不是常量?但是这个呢:

main(){
char * name = "Peter";
}
name
是char*,但是
“Peter”
是const char*,对吗?那么初始化是如何工作的呢

2)
Test(char*c):name(c){c[0]='a';}
-这会使程序崩溃。为什么?

对不起我的无知

为什么
Test(const char*c):name(c){}
不起作用?因为
char*name
不是
const

这个初始化是如何工作的:
char*name=“Peter”

一个C++字符串文字类型是<代码> char const []/Cord>(参见,而不是在代码中仅<代码> char []/COD>,因为它没有<代码> const 向后兼容。

Test(char*c):name(c){c[0]='a';}
使程序崩溃。为什么?

初始化测试时,您将传递什么到
Test
?如果传递字符串文字或非法指针,则不允许执行
c[0]='a'


1旧版本的C编程语言(如1978年出版的K&R书籍所述)没有包含
const
关键字。此后,借用了C++中的代码> const <代码>的思想。 2在C++03中有效,在C++11中不再有效。

1a)对

1b)
“Peter”
不是
const char*
,它是
char*
,但不能修改。原因是与该语言中存在的
const
之前的时间兼容。很多代码已经存在,上面写着
char*p=“fred”

“P>2”不能说明为什么会在不使用构造函数的情况下崩溃程序。

< P>首先,这是C++,你有<代码> STD::String < /C>。你真的应该考虑使用它。

关于你的问题,
“Peter”
是一个字符文本,因此它是不可修改的,当然你不能在上面写。你可以:

  • 拥有一个
    const char*
    成员变量,并像初始化
    name(c)
    一样初始化它,方法是将
    “Peter”
    声明为
    const
  • 使用
    char*
    成员变量并复制内容,例如
    name(strdup(c))
    (记住在析构函数中释放它)
  • “Peter”通常存储在只读内存位置(实际上,它取决于我们使用的设备类型),因为它是一个字符串文本。当您尝试修改字符串文本时会发生什么情况(但您可能会猜测不应该这样做),这是未定义的


  • 无论如何,您应该使用
    std::string

    const
    的转换可以说是一条单行道

    您可以隐式地从
    T*
    转换为
    T const*

    T常量*
    转换到
    T*
    需要显式强制转换。即使您从
    T*
    开始,然后转换到
    T常量*
    ,转换回
    T*
    需要显式强制转换,即使这实际上只是“恢复”您必须开始的访问

    请注意,在整个过程中,
    T const*
    const T*
    是完全等效的,
    T
    代表“某种任意类型”(
    char
    在您的示例中,但也可以很容易地是类似于
    int
    my_user defined_type
    )的东西)

    允许从字符串文本(例如,
    char*s=“whatever”
    )初始化
    char*
    ),即使它违反了此一般规则(文本本身基本上是
    const
    ,但您正在创建指向它的非常量指针)。这只是因为有很多代码依赖于此,而且没有人愿意破坏这些代码,所以他们有一个允许的规则。不过,这个规则已经被弃用,所以至少在理论上,未来的编译器可能会拒绝依赖它的代码

    由于字符串文本本身基本上是常量,任何修改它的尝试都会导致未定义的行为。在大多数现代系统上,这将导致进程终止,因为存储字符串文本的内存将被标记为“只读”。这不是唯一可能的结果。例如,回到过去对于MS-DOS,它通常会成功。但它仍然可能有奇怪的副作用。例如,许多编译器“知道”字符串文字应该是只读的,因此它们会“合并”相同的字符串文字。因此,如果您有以下情况:

    char *a = "Peter"; a[1] = 'a';
    
    char *b = "Peter";
    
    cout << b;
    

    强制一个行为是没有意义的,因此结果是(而且是)没有定义的。

    你说的
    name(c)
    不起作用是什么意思?定义“起作用”。@eit从const char*到char*
    “Peter”
    const char[6]
    ,而不是
    const char*
    。实际上,你想要的是
    std::string name
    @Peter这是考试用的,我认为我们不允许使用std::string,因为它不是课程错误的一部分。这是谁投的票?
    “Peter”
    char const[6]
    ,不是一个
    char*
    @KonradRudolph如果它是
    char const[6]
    那么
    char*name=“Peter”
    legal?1)这是怎么回事:
    Test(const char*c){name=new char[strlen(c)+1];strcpy(name,c)}
    如果我写
    Test t(“Peter”)
    ,构造函数需要常量char*,但是
    “Peter”
    是char*?2) 测试t(“你好”)@john它不合法(在C++11中是合法的,但在C++03中被弃用)。一致性编译器将警告您(在C++03中)或拒绝代码(在C++11中)。
    char*C=“hello”;试验t(c)或只是<代码>测试t
    
    char *a = "this?";
    char *b = "What's this?";
    
    a[2] = 'a';
    a[3] = 't';
    
    cout << b; // could print "What's that?"