Почему вызывается неправильный ctor?

У меня есть код, который работает как ожидалось:

EscapedString es("Abc&def");
EscapedString es2("");
es2 = es;     // es2 == Abc%26def

И код, который не работает, как ожидалось:

EscapedString es("Abc&def");
EscapedString es2 = es;    // es == Abc%2526def

Во втором случае CTOR2 вызывается вместо CTOR3, хотя es является EscapedString.

EscapedString es(EscapedString("Abc?def"));

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

Класс ниже:

class EscapedString : public std::string {
public:
EscapedString(const char *szUnEscaped) {  // CTOR1
*this = szUnEscaped;
}

EscapedString(const std::string &strUnEscaped) {   // CTOR2
*this = strUnEscaped;
}

explicit EscapedString(const EscapedString &strEscaped) {   // CTOR3
*this = strEscaped;  // Can't set breakpoint here
}

EscapedString &operator=(const std::string &strUnEscaped) {
char *szEscaped = curl_easy_escape(NULL, strUnEscaped.c_str(), strUnEscaped.length());
this->assign(szEscaped);
curl_free(szEscaped);
return *this;
}
EscapedString &operator=(const char *szUnEscaped) {
char *szEscaped = curl_easy_escape(NULL, szUnEscaped, strlen(szUnEscaped));
this->assign(szEscaped);
curl_free(szEscaped);
return *this;
}
EscapedString &operator=(const EscapedString &strEscaped) {
// Don't re-escape the escaped value
this->assign(static_cast<const std::string &>(strEscaped));
return *this;
}
};

4

Решение

Обычно, EscapedString es2 = es; вызовет конструктор копирования, однако вы явно запретили это делать конструктором копирования explicit:

explicit EscapedString(const EscapedString &strEscaped)

Конструктор отмечен explicit никогда не может быть вызван с помощью автоматического преобразования типов. Он может быть вызван только, ну … явно, что вы сделали здесь:

EscapedString es(EscapedString("Abc?def"));

Вот что происходит, когда компилятор встречает EscapedString es2 = es;,

Сначала компилятор видит, может ли он использовать конструктор копирования, и обнаруживает, что он не может этого сделать, потому что он был помечен. explicit, Так что он ищет другого конструктора для вызова. поскольку EscapedString происходит от std::string, компилятор может привести es как const std::string& и позвоните:

EscapedString &operator=(const std::string &strUnEscaped)
10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]