2015-04-16 2 views
3

У меня вопрос о пользовательском преобразовании.C++ Определенное пользователем преобразование - неявное преобразование

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*(). Я делаю что-то неправильно?

+4

http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – 0x499602D2

+1

Короче говоря: оператор присваивания 'String & operator = (const String & other)' отсутствует. – haavee

ответ

7

Вы забыли определить 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; 
} 

Из-за того, что ваш компилятор должен был определить оператор присваивания копии «по умолчанию», которая просто присваивает все поля «другой» к текущему объекту:

String& operator=(const String& other) { 
    m_data = other.m_data; 
    return *this; 
} 

Так у вас есть два указателя на то же m_data в a и b и на выходе из main, delete[] будет называться дважды.

+3

Пожалуйста, добавьте чеки, чтобы позаботиться о самостоятельном назначении, и это не должно быть op. –

+0

Вы проверили, что оператор присваивания копии генерируется, когда задан оператор присваивания (а не присвоение копии). –

Смежные вопросы