重载C++赋值运算符

Kol*_*nya 1 c++ overloading operator-overloading variable-assignment assignment-operator

我想扩展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;

}
Run Code Online (Sandbox Code Playgroud)

For*_*veR 10

String bar = foo;
Run Code Online (Sandbox Code Playgroud)

它是复制初始化(等效于

String bar(String(foo));
Run Code Online (Sandbox Code Playgroud)

),而不是任务.您应该为此工作实现复制构造函数(或默认初始化变量,然后分配foobar).

无论如何,从标准C++类型派生是个坏主意,因为这些类型没有虚拟析构函数.并且组合甚至比继承更好,在你的例子中,你应该使用组合.


riv*_*riv 9

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

String bar;
bar = foo;
Run Code Online (Sandbox Code Playgroud)

您的赋值运算符将按预期调用.


Gor*_*pik 6

这里的问题是你的路线

String bar = foo;
Run Code Online (Sandbox Code Playgroud)

不调用赋值运算符,因为没有要分配的对象(bar尚未创建); 它调用一个构造函数.实际上,如果它可用,它会调用你注释掉的构造函数.

如果你真的想使用你的运营商,你必须写:

String bar;
bar = foo; // Now bar exists and you can assign to it
Run Code Online (Sandbox Code Playgroud)

顺便说一句,继承自然std::string并不是一个好主意,因为这个类与标准库中的大多数其他类一样,并不是为了继承而设计的.具体来说,它缺少一个虚拟析构函数,如果你以多态方式使用它会导致麻烦,例如:

std::string* str = new String();
delete str; // Oops; the wrong destructor will be called
Run Code Online (Sandbox Code Playgroud)

  • @EmilioGaravaglia:这是"与可能的错误的距离"的问题.从没有虚拟析构函数的类派生本身并不是一个错误,但是拥有这样一个类会让你的客户*更接近错误,因为现在你必须*记录*行为的特殊性.我们都知道*发生的可能性有多大.(写作和阅读.)对于初学者,你倾向于提供通用建议,而这次是"不扩展标准类". (2认同)