C++复制构造函数不调用(编译错误)
这段代码没有编译请忽略运算符+中的值传递,我可以用引用替换它&但它仍然不能解决问题 我希望在主要功能方面:C++复制构造函数不调用(编译错误),c++,constructor,compilation,copy,C++,Constructor,Compilation,Copy,这段代码没有编译请忽略运算符+中的值传递,我可以用引用替换它&但它仍然不能解决问题 我希望在主要功能方面: String s3 = s + s2; // COMPILATION ERROR 要编译是可以的,因为我声明了复制构造函数,但它没有给出匹配的构造函数 #include <iostream> #include <string> class String { public: String() { std::cout <<
String s3 = s + s2; // COMPILATION ERROR
要编译是可以的,因为我声明了复制构造函数,但它没有给出匹配的构造函数
#include <iostream>
#include <string>
class String {
public:
String()
{
std::cout << "Constructor " << this << std::endl;
data = new char[100];
};
String(char * str) : String()
{
std::cout << "Char * Constructor " << this << std::endl;
strcpy(this->data,str);
};
String(String & rhs) : String() {
std::cout << "Copy Constructor " << this << std::endl;
strcpy(data, rhs.data);
};
void print() {
printf("%s\n",data);
}
~String() {
std::cout << "Destructor " << this << std::endl;
if (data) {
delete data;
data = nullptr;
}
};
friend String operator+(String s1, String s2);
private:
char * data;
};
String operator+(String s1, String s2)
{
String temp;
delete [] temp.data;
temp.data =
new char[strlen(s1.data) + strlen(s2.data) + 1];
strcpy(temp.data, s1.data);
strcat(temp.data, s2.data);
return temp;
}
int main(int argc, const char * argv[])
{
String s("herer");
s.print();
String s2 = s;
s2.print();
String s3 = s + s2; // COMPILATION ERROR
return 0;
}
String(String & rhs)
复制构造函数的参数必须是const&
您的代码有几个错误。首先
String(char * str)
需要
String(const char * str)
如果要像在main中一样使用字符串文本,请使用string sherr;。其次,复制构造函数
#include <iostream>
#include <string>
class String {
public:
String()
{
std::cout << "Constructor " << this << std::endl;
data = new char[100];
};
String(char * str) : String()
{
std::cout << "Char * Constructor " << this << std::endl;
strcpy(this->data,str);
};
String(String & rhs) : String() {
std::cout << "Copy Constructor " << this << std::endl;
strcpy(data, rhs.data);
};
void print() {
printf("%s\n",data);
}
~String() {
std::cout << "Destructor " << this << std::endl;
if (data) {
delete data;
data = nullptr;
}
};
friend String operator+(String s1, String s2);
private:
char * data;
};
String operator+(String s1, String s2)
{
String temp;
delete [] temp.data;
temp.data =
new char[strlen(s1.data) + strlen(s2.data) + 1];
strcpy(temp.data, s1.data);
strcat(temp.data, s2.data);
return temp;
}
int main(int argc, const char * argv[])
{
String s("herer");
s.print();
String s2 = s;
s2.print();
String s3 = s + s2; // COMPILATION ERROR
return 0;
}
String(String & rhs)
需要采取行动
String(const String & rhs)
这样它就可以绑定到临时对象
第三,为了使用strcpy,您需要包含或
最后,您在析构函数中使用了错误的delete。调用new时使用delete,使用new[]时调用delete[]。您使用new[]分配数据,但使用delete删除数据
您可以看到代码的工作示例如果输入字符串包含100个以上的字符,会发生什么?通过常量引用将字符串传递给运算符以避免复制。不要删除字符串对象外部的内部数据,就像在运算符中一样。这违背了C++的优点。在external friend operator+中,如何更好地组织代码以不访问内部数据?字符串构造函数应该找出输入字符串的大小并分配正确的内存量。您还应该实现一个赋值运算符。感谢详细的代码审阅。现在更清楚了。因此编译器不允许非常量参数绑定到临时对象。顺便问一下,为什么它允许我在operator+中使用这个非常量复制构造函数呢?我的意思是,即使我使用reference&形式的itA reference也不能绑定到右值,这就是s+s2的结果。引用只能绑定到获取其名称的左值,因为它可以位于=符号的左侧。这就是为什么你可以在操作符+中复制它们,但是你不能复制它的结果,因为返回的字符串不是左值。哦,现在我明白了。这是有道理的。如果我使用带有地址的左值对象,编译器将使用复制构造函数的非常量引用形式。但是临时的s+s2表达式是右值,所以编译器不能用非常量引用绑定到它!我只能假设它是由于右值结果,所以无论如何都会被浪费掉,所以不需要使它可变,这就是为什么Compiler显式要求const ness的原因,非常感谢。这是有洞察力的:@巴尼,如果这个或任何答案已经解决了你的问题,请考虑通过点击复选标记。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。没有义务这么做,还有更多的话要说。不幸的是,编译器不够智能,无法以更明确的方式指出这种类型转换问题。我必须有一些外部知识才能理解这个问题。只是到处有C++的高级编译器或静态分析器能立即显示问题吗?