类赋值运算符

发布于 2024-10-08 16:27:45 字数 1018 浏览 8 评论 0原文

我进行了以下运算符重载测试:

#include <iostream>
#include <string>

using namespace std;

class TestClass
{
    string ClassName;

    public:

    TestClass(string Name)
    {
        ClassName = Name;
        cout << ClassName << " constructed." << endl;
    }

    ~TestClass()
    {
        cout << ClassName << " destructed." << endl;
    }

    void operator=(TestClass Other)
    {
        cout << ClassName << " in operator=" << endl;
        cout << "The address of the other class is " << &Other << "." << endl;
    }
};

int main()
{
    TestClass FirstInstance("FirstInstance");
    TestClass SecondInstance("SecondInstance");

    FirstInstance = SecondInstance;
    SecondInstance = FirstInstance;

    return 0;
}

赋值运算符的行为符合预期,输出另一个实例的地址。

现在,我实际上如何从另一个实例分配一些东西?例如,这样的事情:

void operator=(TestClass Other)
{
    ClassName = Other.ClassName;
}

I made the following operator overloading test:

#include <iostream>
#include <string>

using namespace std;

class TestClass
{
    string ClassName;

    public:

    TestClass(string Name)
    {
        ClassName = Name;
        cout << ClassName << " constructed." << endl;
    }

    ~TestClass()
    {
        cout << ClassName << " destructed." << endl;
    }

    void operator=(TestClass Other)
    {
        cout << ClassName << " in operator=" << endl;
        cout << "The address of the other class is " << &Other << "." << endl;
    }
};

int main()
{
    TestClass FirstInstance("FirstInstance");
    TestClass SecondInstance("SecondInstance");

    FirstInstance = SecondInstance;
    SecondInstance = FirstInstance;

    return 0;
}

The assignment operator behaves as-expected, outputting the address of the other instance.

Now, how would I actually assign something from the other instance? For example, something like this:

void operator=(TestClass Other)
{
    ClassName = Other.ClassName;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

云淡风轻 2024-10-15 16:27:46

传统上,赋值运算符和复制构造函数是通过 const 引用定义的,而不是使用按值复制机制。

class TestClass 
{
public:
    //... 
    TestClass& operator=(const TestClass& Other)
    {
        m_ClassName= Other.m_ClassName;
        return *this;
    }
private:
    std::string m_ClassName;
 }

编辑:我更正了,因为我放置的代码没有返回 TestClass& (参见@sbi的回答)

Traditionnaly the assignment operator and the copy constructor are defined passing a const reference, and not with a copy by value mechanism.

class TestClass 
{
public:
    //... 
    TestClass& operator=(const TestClass& Other)
    {
        m_ClassName= Other.m_ClassName;
        return *this;
    }
private:
    std::string m_ClassName;
 }

EDIT: I corrected because I had put code that didnt return the TestClass& (c.f. @sbi 's answer)

_畞蕅 2024-10-15 16:27:46

关于如何从其他班级复制内容,您是正确的。简单的对象可以使用operator=来赋值。

但是,要警惕 TestClass 包含指针成员的情况 - 如果您只是使用 operator= 分配指针,那么两个对象将具有指向同一内存的指针,这可能不是你想要的。相反,您可能需要确保分配一些新内存并将指向的数据复制到其中,以便两个对象都有自己的数据副本。请记住,在为复制的数据分配新块之前,您还需要正确释放分配对象已指向的内存。

顺便说一句,您可能应该像这样声明您的 operator=

TestClass & operator=(const TestClass & Other)
{
    ClassName = Other.ClassName;
    return *this;
}

这是重载 operator= 时使用的一般约定。 return 语句允许链接赋值(如 a = b = c),并通过 const 引用传递参数,避免将 Other 复制到函数调用。

You are correct about how to copy the contents from the other class. Simple objects can just be assigned using operator=.

However, be wary of cases where TestClass contains pointer members -- if you just assign the pointer using operator=, then both objects will have pointers pointing to the same memory, which may not be what you want. You may instead need to make sure you allocate some new memory and copy the pointed-to data into it so both objects have their own copy of the data. Remember you also need to properly deallocate the memory already pointed to by the assigned-to object before allocating a new block for the copied data.

By the way, you should probably declare your operator= like this:

TestClass & operator=(const TestClass & Other)
{
    ClassName = Other.ClassName;
    return *this;
}

This is the general convention used when overloading operator=. The return statement allows chaining of assignments (like a = b = c) and passing the parameter by const reference avoids copying Other on its way into the function call.

醉态萌生 2024-10-15 16:27:45

你所展示的代码就可以做到这一点。但没有人会认为这是一个特别好的实现。

这符合赋值运算符的预期:

TestClass& operator=(TestClass other)
{
    using std::swap;
    swap(ClassName, other.ClassName);
    // repeat for other member variables;
    return *this;
}

顺便说一句,您谈论“其他类”,但您只有一个类,以及该类的多个实例。

The code you've shown would do it. No one would consider it to be a particularly good implementation, though.

This conforms to what is expected of an assignment operator:

TestClass& operator=(TestClass other)
{
    using std::swap;
    swap(ClassName, other.ClassName);
    // repeat for other member variables;
    return *this;
}

BTW, you talk about "other class", but you have only one class, and multiple instances of that class.

绝對不後悔。 2024-10-15 16:27:45

赋值运算符的传统规范形式如下所示:(

TestClass& operator=(const TestClass& Other);

您也不想调用复制构造函数进行赋值)并且它返回对 *this 的引用。

一个幼稚的实现将单独分配每个数据成员:(

TestClass& operator=(const TestClass& Other)
{
  ClassName = Other.ClassName;
  return *this;
}

请注意,这正是编译器生成的赋值运算符要做的事情,因此重载它是毫无用处的。不过,我认为这是为了练习。)

更好的方法是是采用Copy-And-Swap idiom< /a>。 (如果您发现 GMan 的答案太过压倒性,请尝试我的,这不太详尽。:))请注意,C&S 使用复制构造函数和析构函数进行赋值,因此需要按副本传递对象,正如您在问题中所提到的:

TestClass& operator=(TestClass Other)

The traditional canonical form of the assignment operator looks like this:

TestClass& operator=(const TestClass& Other);

(you don't want to invoke the copy constructor for assignment, too) and it returns a reference to *this.

A naive implementation would assign each data member individually:

TestClass& operator=(const TestClass& Other)
{
  ClassName = Other.ClassName;
  return *this;
}

(Note that this is exactly what the compiler-generated assignment operator would do, so it's pretty useless to overload it. I take it that this is for exercising, though.)

A better approach would be to employ the Copy-And-Swap idiom. (If you find GMan's answer too overwhelming, try mine, which is less exhaustive. :)) Note that C&S employs the copy constructor and destructor to do assignment and therefore requires the object to be passed per copy, as you had in your question:

TestClass& operator=(TestClass Other)
终止放荡 2024-10-15 16:27:45

几乎所有人都说了,有一些注意事项:

  • 检查自分配,即 if (&other != this) // allocate
  • 在这里查看有关 运算符重载

almost all said, a few notes:

  • check for self-assignment, i.e. if (&other != this) // assign
  • look here for an excellent guide on operator overloading
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文