'Explicit copy constructor

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



Solution 1:[1]

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"));

Solution 2:[2]

It seems current gcc won't invoke the copy constructor tested in gcc 8.2(MinGW.org GCC-8.2.0-5)?and will utilize to call constructor directly For X1

#include <iostream>

using std::cout;
using std::endl;


class X1 {
public:

    X1() {
        cout<< "invoke constructor" << endl;
    }; 

    explicit X1(const X1 &obj)  { 
        cout << "invoke copy constructor" << endl;
    };

    X1(X1&& obj)  {
        cout << "invoke move constructor" << endl;
    };

    X1& operator=(const X1 &obj) {
        cout << "invoke value assign constructor " << endl;
        if(this == &obj) {
            return *this;
        }
        return *this;
    };

    X1& operator=(const X1 && obj) {
        cout << "invoke move value assign constructor " << endl;
        if(this == &obj) {
            return *this;
        }
        return *this;

    };

    ~X1() {
        cout << "invoke deconstruct" << endl;
    };



};

int main() {
//    X1 l1(1);
//    X1 l3(2);
    X1 l4 = X1();

    return 0;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 metamorphosis
Solution 2 truejasonxiefans