Explicit copy constructor

abumusamq picture abumusamq · Jul 14, 2012 · Viewed 23.9k times · Source

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".

Answer

David Rodr&#237;guez - dribeas picture David Rodríguez - dribeas · Jul 14, 2012

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...