c ++用户定义的转换 - 隐式转换

Nef*_*pus 3 c++ type-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;
    }
};
Run Code Online (Sandbox Code Playgroud)

虽然这有效:

int main(int argc, char** argv) {
    String a;
    String b;
    a = "aaa";
    b = (const char *)a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不是:

int main(int argc, char** argv) {
    String a;
    String b;
    a = "aaa";
    b = a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到double free or corruption运行时错误.Valgrind说了一些关于无效删除的事情.

为什么我必须明确地对它进行类型转换?我认为它会以这种方式工作explicit operator const char*().难道我做错了什么?

mya*_*aut 7

您忘了定义复制赋值运算符:

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;
}
Run Code Online (Sandbox Code Playgroud)

因此,您的编译器必须定义"默认"复制赋值运算符,简单地将"other"的所有字段分配给当前对象:

String& operator=(const String& other) {
    m_data = other.m_data;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

所以你有两个指向同一个m_datain aband的出口main,delete[]将被调用两次.

  • 请添加检查以处理自我分配,这应该是一个无操作. (3认同)