У меня есть код, который работает как ожидалось:
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;
}
};
Обычно, 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)
Других решений пока нет …