好的,我能用c ++构造函数理解这些东西:
如果我使用初始化列表方法,代码可以工作:
Client::Client() : id(), name(){
// this works!
}
但常规方法并不是:
Client::Client(){
id = String();
name = String();
// does not work
}
String只是我写的另一个类; String默认构造函数如下:
String::String(){
str = NULL;
}
Afaik,初始化列表允许你初始化consts和references,但我真的不知道它在这里有什么帮助?
我错过了什么?
编辑:声明:
class String {
char *str;
public:
String();
String & operator =(const String &rhs);
}
class Client {
String id, name;
public:
Client();
};
String确实有一个赋值运算符,但我想用它来复制" str"的内容。进入lhs String,这可能是问题吗?因为它试图使用我的赋值运算符并失败?
解决:
好的,它确实是赋值运算符,似乎如果我给它一个str = NULL的字符串,它就无法strcpy并停止程序。抱歉没有准确,我确实尝试调试,发现它失败@客户端的构造函数,当我尝试初始化String变量时,因为我有更多的代码。所以我理解第一种初始化方法是,因为它只是直接使用赋值运算符。
String & String::operator =(const String &rhs){
/*if(!rhs.str){ return *this; }*/ // had to add this line!
str = new char[strlen(rhs.str)];
strcpy(str, rhs.str);
return *this;
}
谢谢你们。
非常感谢, 迈克尔。
答案 0 :(得分:1)
它无法strcpy并停止程序
嗯,这是你的错误。在第id = String();
行中,您使用String
以str
成员作为参数调用复制作业。您的副本赋值运算符显然会从具有未定义行为的空指针尝试strcpy
。
我可以给你的最佳建议是“使用std::string
”。
所以我理解第一种初始化方法是有效的,因为它只是直接使用赋值运算符,这是正确的吗?
正确。两个版本都默认构造成员,但第二个版本也会复制作业。如果默认初始化足够,则根本不需要为Client
设置用户定义的构造函数。
答案 1 :(得分:1)
这两个构造函数实现之间的区别在于前者显式地默认构造元素,而第二个是隐式构造,然后在默认构造的实例上调用赋值运算符。
Client::Client() : id(), name(){
}
Client::Client(){
id = String();
name = String();
}
如果您的分配操作符被破坏,则第一个版本将起作用,第二个版本将失败。
你应该总是更喜欢在构造函数体中初始化初始化列表,因为后者会导致不必要的构造,然后是赋值。