18

我已经扩展了 std::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");

我不确定在哪里明确需要强制转换。

如果复制构造函数不是显式的,则代码可以正常工作,但我想知道并实现显式定义而不是“猜测正确的强制转换”。

4

2 回答 2

43

显式复制构造函数意味着不会隐式调用复制构造函数,这就是表达式中发生的情况:

CustomString s = CustomString("test");

这个表达式的字面意思是:CustomString使用带有const char*. 隐式调用 的复制构造函数CustomString以从该临时复制到s.

现在,如果代码是正确的(即如果复制构造函数不是显式的),编译器将避免创建临时代码并通过s直接使用字符串字面量构造来省略复制。但是编译器仍然必须检查构造是否可以完成并且在那里失败。

您可以显式调用复制构造函数:

CustomString s( CustomString("test") );

但我建议您完全避免临时使用,只需s使用以下命令创建const char*

CustomString s( "test" );

这就是编译器无论如何都会做的事情......

于 2012-07-14T02:57:52.917 回答
6

从 std::string 派生是不安全的,因为 std::string 没有虚拟析构函数。至于您的问题-您的复制构造函数不应该是明确的,以允许以下用法:

CustomString s = "test";

此外,我不知道您为什么要将复制构造函数声明为显式,因为它不是必需的。仅当您将 CustomString 对象声明为:

CustomString s(CustomString("test"));
于 2012-07-14T02:32:31.470 回答