Explicit copy constructor

28,158

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"));
Share:
28,158

Related videos on Youtube

abumusamq
Author by

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, 2022

Comments

  • abumusamq
    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
    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
    ForEveR almost 12 years
    @DavidRodríguez-dribeas when ildjarn posting comment, answer was rather shorter.
  • abumusamq
    abumusamq almost 12 years
    Oh 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
    abumusamq almost 12 years
    Thanks 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
    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
    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
    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
    Joshua Green over 9 years
    As long as the OP only uses CustomStrings and doesn't, say, try to delete a new CustomString through a std::string pointer, is there really anything unsafe about this derivation?
  • spectras
    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 "[...]".