重载c++赋值操作符

Overloading the C++ assignment operator

本文关键字:赋值操作符 c++ 重载      更新时间:2023-10-16

我想用一些功能扩展std::string,所以我从它派生出String。为了使代码像String str = stdStr;工作,我试图重载赋值运算符,但我的代码没有被调用某种原因。我该怎么修理它?

#include <string>
class String
    :
        public std::string
{
    public:
        /*
        I do know that this constructor will solve the problem, but is it possible to use the operator?
        String ( const std::string& stdString )
        {
            ...
        }
        */
        String& operator= ( const std::string& stdString )
        {
            ...
            return *this;
        }
};
int main()
{
    std::string foo = "foo";
    String bar = foo;
    return 1;
}
String bar = foo;

复制初始化(相当于

)
String bar(String(foo));

),而不是赋值。您应该为此实现复制构造函数(或默认初始化变量,然后将foo分配给bar)。

无论如何,从标准c++类型派生不是一个好主意,因为这些类型没有虚析构函数。合成甚至比继承更好,在你的例子中,你应该使用合成

String bar = foo行不是赋值,它实际上相当于String bar(foo)。如果你写

String bar;
bar = foo;

您的赋值操作符将被调用,如预期的。

这里的问题是你的行

String bar = foo;

不调用赋值操作符,因为没有对象可以赋值(bar还没有创建);它调用构造函数。实际上,如果有被注释掉的构造函数,它会调用它。

如果你真的想使用你的操作符,你必须这样写:

String bar;
bar = foo; // Now bar exists and you can assign to it
顺便说一下,从std::string继承并不是一个好主意,因为这个类和标准库中的大多数其他类一样,不是被设计为可以继承的。具体来说,它缺少一个虚拟析构函数,如果以多态方式使用它会导致麻烦,例如:
std::string* str = new String();
delete str; // Oops; the wrong destructor will be called

在您的例子中,尽管= present,新的String对象将被创建,因此需要

String ( const std::string& stdString )  

不加注释。另一个选项是像

这样
String bar;  
bar = foo;  

但这听起来不像是一个好主意

这样做使用复制构造函数:

String foo("foo");
String foo="hello";//assignment operator here

但这不是:

String foo;
String foo="hello";//copy constructor used here since foo was not initialized

其他被点赞的答案都是消息灵通的

为了直接回答你的问题,你试着这样做。

    String& operator= ( const std::string& stdString )
    {
        // Call the base implementation
        return std::string::operator= ( stdString );
    }

std::string foo =" foo";String bar = foo;

您在main中尝试的操作不会调用复制赋值操作符。它相当于调用复制构造函数。

最好避免继承std::string,因为它没有定义虚析构函数。