Explicit copy constructor
Solution 1
The explicit copy constructor means that the copy constructor will not be called implicitly, which is what happens in the expression:
CustomString s = CustomString("test");
This expression literally means: create a temporary CustomString
using the constructor that takes a const char*
. Implicitly call the copy constructor of CustomString
to copy from that temporary into s
.
Now, if the code was correct (i.e. if the copy constructor was not explicit), the compiler would avoid the creation of the temporary and elide the copy by constructing s
directly with the string literal. But the compiler must still check that the construction can be done and fails there.
You can call the copy constructor explicitly:
CustomString s( CustomString("test") );
But I would recommend that you avoid the temporary altogether and just create s
with the const char*
:
CustomString s( "test" );
Which is what the compiler would do anyway...
Solution 2
Deriving from std::string is not safe, as std::string has no virtual destructor. As to your question - your copy constructors should not be explicit, to allow for such usage as:
CustomString s = "test";
Also I have no idea why you would want to declare a copy-constructor as explicit, as it is not needed. An explicit copy-constructor will work only if you declare your CustomString object as:
CustomString s(CustomString("test"));
Related videos on Youtube
abumusamq
I have over 16 years of experience as a software developer with great passion for web technologies. Mostly self-learned, I never cease to learn new technologies. I'm particularly interested in web performance and techniques to speed up the devops. I have a vast range of expertise in various platforms, programming languages and frameworks. I've recently developed my love for cloud-native.
Updated on July 05, 2022Comments
-
abumusamq almost 2 years
I have extended std::string to fulfil my needs of having to write custom function build into string class called CustomString
I have defined constructors:
class CustomString : public std::string { public: explicit CustomString(void); explicit CustomString(const std::string& str); explicit CustomString(const CustomString& customString); //assignment operator CustomString& operator=(const CustomString& customString); ... };
In the third constructor (copy constructor) and assignment operator, whose definition is:
CustomString::CustomString(const CustomString& customString): std::string(static_cast<std::string>(customString)) {} CustomString& CustomString::operator=(const CustomString& customString){ this->assign(static_cast<std::string>(customString)); return *this; }
First since this is an "explicit"; meaning an explicit cast is needed to assign to another CustomString object; it's complaining about the assignment.
CustomString s = CustomString("test");
I am not sure where exactly is casting needed explicitly.
The code works alright if copy constructor is not explicit but I would like to know and implement explicit definition instead of "guessing proper cast".
-
David Rodríguez - dribeas almost 12 years@ildjarn: why lazy? It is correct (not optimal, but correct) tackles the problem and provides a solution...
-
ForEveR almost 12 years@DavidRodríguez-dribeas when ildjarn posting comment, answer was rather shorter.
-
abumusamq almost 12 yearsOh yea I completely understand your answer (and it is proper answer and I have marked it as best answer) but how would I achieve
CustomString s = customStringObjectOnStack;
for example? -
abumusamq almost 12 yearsThanks and nice answer but this is lazy because I have asked this to improve my way of writing code instead of just getting thing done. Thanks anyways :)
-
ForEveR almost 12 years@mkhan3189 you can achieve CustomString s = customStringObjectOnStack if and only if copy-ctor will not be explicit. For second question, kDelimited is CustomString or something else? And + your function is const, so c.append(static_cast<const std::string&>(*this)) will works.
-
abumusamq almost 12 years@ForEveR Yea Thanks for that. I got the answer myself. kDelimiter is CustomString constant object, yes.
c.append(static_cast<std::string>(*this))
works for implicit copy-ctor declaration. So all good. This thread can be closed. -
David Rodríguez - dribeas almost 12 years@mkhan3189: You can achieve
CustomString s = customStringObjectOnStack;
by instead of implicitly using that copy constructor with the=
syntax, you explicitly call the copy constructor:CustomString s( customStringObjectOnStack );
-
Joshua Green over 9 yearsAs long as the OP only uses
CustomString
s and doesn't, say, try todelete
anew CustomString
through astd::string
pointer, is there really anything unsafe about this derivation? -
spectras over 3 years“As long as [...], is there anything unsafe?”. Unless you have the means to enforce the conditions reliably and consistently over time, including coworker's code and wherever this might get copy-pasted to in the future, the answer to that question is always yes. No matter what's in the "[...]".