c ++用户定义的转换 - 隐式转换
c++ User defined conversion - implicit conversion
我对用户定义的转换有疑问。
class String {
char* m_data;
public:
String(): m_data(NULL) {}
String(const char* cstr): m_data(new char[strlen(cstr)+1]) {
strcpy(m_data, cstr);
}
~String() {
delete[] m_data;
}
String& operator=(const char* cstr) {
delete[] m_data;
m_data = new char[strlen(cstr)+1];
strcpy(m_data, cstr);
return *this;
}
operator const char*() const {
return m_data;
}
};
虽然这有效:
int main(int argc, char** argv) {
String a;
String b;
a = "aaa";
b = (const char *)a;
return 0;
}
这不是:
int main(int argc, char** argv) {
String a;
String b;
a = "aaa";
b = a;
return 0;
}
我收到 double free or corruption
运行时错误。 Valgrind 说了一些关于无效删除的事情。
为什么我必须明确地对其进行类型转换?我认为 explicit operator const char*()
会以这种方式工作。我做错了什么吗?
您忘记定义 copy assignment operator:
String& operator=(const String& other) {
if(this != &other) {
char* new_data = new char[strlen(other.m_data)+1];
strcpy(new_data, other.m_data);
delete[] m_data;
m_data = new_data;
}
return *this;
}
因此您的编译器必须定义 "default" 复制赋值运算符,它简单地将 "other" 的所有字段分配给当前对象:
String& operator=(const String& other) {
m_data = other.m_data;
return *this;
}
所以你在 a
和 b
中有两个指向相同 m_data
的指针,并且在从 main
退出时, delete[]
将被调用两次。
我对用户定义的转换有疑问。
class String {
char* m_data;
public:
String(): m_data(NULL) {}
String(const char* cstr): m_data(new char[strlen(cstr)+1]) {
strcpy(m_data, cstr);
}
~String() {
delete[] m_data;
}
String& operator=(const char* cstr) {
delete[] m_data;
m_data = new char[strlen(cstr)+1];
strcpy(m_data, cstr);
return *this;
}
operator const char*() const {
return m_data;
}
};
虽然这有效:
int main(int argc, char** argv) {
String a;
String b;
a = "aaa";
b = (const char *)a;
return 0;
}
这不是:
int main(int argc, char** argv) {
String a;
String b;
a = "aaa";
b = a;
return 0;
}
我收到 double free or corruption
运行时错误。 Valgrind 说了一些关于无效删除的事情。
为什么我必须明确地对其进行类型转换?我认为 explicit operator const char*()
会以这种方式工作。我做错了什么吗?
您忘记定义 copy assignment operator:
String& operator=(const String& other) {
if(this != &other) {
char* new_data = new char[strlen(other.m_data)+1];
strcpy(new_data, other.m_data);
delete[] m_data;
m_data = new_data;
}
return *this;
}
因此您的编译器必须定义 "default" 复制赋值运算符,它简单地将 "other" 的所有字段分配给当前对象:
String& operator=(const String& other) {
m_data = other.m_data;
return *this;
}
所以你在 a
和 b
中有两个指向相同 m_data
的指针,并且在从 main
退出时, delete[]
将被调用两次。