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