Явный конструктор копирования

Я расширил std::string, чтобы удовлетворить мои потребности в необходимости создания встроенной функции в класс string под CustomString

Я определил конструкторы:

    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);
    ... };

В третьем конструкторе (конструкторе копирования) и операторе присваивания, определение которого:

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;
}

Сначала, поскольку это "явный"; это означает, что для привязки к другому объекту CustomString требуется явное приведение; он жалуется на назначение.

CustomString s = CustomString("test");

Я не уверен, где именно явно требуется кастинг.

Код работает нормально, если конструктор копирования не является явным, но я хотел бы знать и реализовывать явное определение вместо "угадывать правильный приведение".

Ответ 1

Явный конструктор копирования означает, что конструктор копирования не будет называться неявно, что и происходит в выражении:

CustomString s = CustomString("test");

Это выражение буквально означает: создать временный CustomString с помощью конструктора, который принимает const char*. Неявно вызвать конструктор копирования CustomString для копирования из этого временного в s.

Теперь, если код был прав (т.е. если конструктор копирования не был явным), компилятор избежал бы создания временного и исключил бы копию, построив s непосредственно с строковым литералом. Но компилятор все равно должен проверить, что конструкция может быть выполнена и не работает.

Вы можете явно вызвать конструктор копирования:

CustomString s( CustomString("test") );

Но я бы посоветовал вам вообще избегать временного и просто создать s с помощью const char*:

CustomString s( "test" );

Это то, что сделает компилятор в любом случае...

Ответ 2

Вывод из std::string небезопасен, поскольку std::string не имеет виртуального деструктора. Что касается вашего вопроса - ваши конструкторы копий не должны быть явными, чтобы разрешить такое использование:

CustomString s = "test";

Также я понятия не имею, почему вы хотите объявить экземпляр-конструктор как явный, поскольку он не нужен. Явный конструктор копирования будет работать, только если вы объявите свой объект CustomString как:

CustomString s(CustomString("test"));