Why is ctor not so called?

I have some code that works as expected:

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

And code that does not work as expected:

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

In the second case, CTOR2 is called instead of CTOR3, although es is EscapedString.

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

That's right, but I can't set a breakpoint on CTOR3, so I'm not sure if it works correctly, or the code has been optimized or it accidentally works.

Class below:

 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
source share
1 answer

Usually EscapedString es2 = es; calls the copy constructor, however you explicitly told it not to explicit copy the constructor:

 explicit EscapedString(const EscapedString &strEscaped) 

A constructor labeled explicit never be called using automatic type conversions. It can be called, but ... obviously, what you did here:

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

This is what happens when the compiler encounters EscapedString es2 = es; .

First, the compiler sees if it can use the copy constructor and discovers that it cannot, since it was explicit marked. Therefore, he is looking for another constructor to call. Since EscapedString is derived from std::string , the compiler can use es as const std::string& and call:

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

Source: https://habr.com/ru/post/1483814/


All Articles