获取“此”的副本(当前实例)在 C++ 中

发布于 2024-09-28 09:48:05 字数 411 浏览 4 评论 0原文

我想要当前正在运行的实例的副本。

当我更改副本中的值时,原始对象也会受到影响。该副本充当实例。

如何避免这种情况?我需要创建调用对象的独立副本。

 Set operator+(Set s){
             Set temp = *this;  

             for(int i=0; s.elements[i] != '\0'; i++){
                     temp(s.elements[i]);
             }
             temp.elements[0] = 'X'; // <- this affects calling object also :(

             return temp;

         }

I want to have a copy of the currently running instance.

When i change a value in the copy, original object is also affected. The copy acts as an instance.

How to avoid this? I need to create an independent copy of the calling object.

 Set operator+(Set s){
             Set temp = *this;  

             for(int i=0; s.elements[i] != '\0'; i++){
                     temp(s.elements[i]);
             }
             temp.elements[0] = 'X'; // <- this affects calling object also :(

             return temp;

         }

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

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

发布评论

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

评论(6

画中仙 2024-10-05 09:48:05

问题在于 Set temp = *this; 进行浅复制,而不是深复制。您必须修改 Set 类的复制构造函数和赋值运算符,以便它们复制所有成员/包含的对象。

例如:

class Set
{
public:
    Set()
    {
        elements = new SomeOtherObject[12];
        // Could make elements a std::vector<SomeOtherObject>, instead
    }

    Set(const Set& other)
    {
        AssignFrom(other);
    }

    Set& operator=(const Set& other)
    {
        AssignFrom(other);
        return *this;
    }

private:
    void AssignFrom(const Set& other)
    {
        // Make copies of entire array here, as deep as you need to.
        // You could simply do a top-level deep copy, if you control all the
        // other objects, and make them do top-level deep copies, as well
    }

    SomeOtherObject* elements;
};

The problem is that Set temp = *this; makes a shallow copy, not a deep copy. You will have to modify the copy constructor and assignment operators for the Set class so that they make copies of all the member/contained objects.

E.g:

class Set
{
public:
    Set()
    {
        elements = new SomeOtherObject[12];
        // Could make elements a std::vector<SomeOtherObject>, instead
    }

    Set(const Set& other)
    {
        AssignFrom(other);
    }

    Set& operator=(const Set& other)
    {
        AssignFrom(other);
        return *this;
    }

private:
    void AssignFrom(const Set& other)
    {
        // Make copies of entire array here, as deep as you need to.
        // You could simply do a top-level deep copy, if you control all the
        // other objects, and make them do top-level deep copies, as well
    }

    SomeOtherObject* elements;
};
美人如玉 2024-10-05 09:48:05

并不是说您的函数已经制作了两个副本,因为它接受其参数并返回每个副本的结果:

Set operator+(Set s);

因此您不必复制s,因为它已经被复制了。我想这是非自愿的,所以你可能想阅读如何将对象传递给函数如何在 C++ 中从函数返回对象

不过,您报告的问题暗示您的复制构造函数无法正常工作。您是否实现了复制构造函数,或者使用了编译器提供的复制构造函数?

Not that your function already makes two copies, since it takes its argument and returns its result per copy:

Set operator+(Set s);

So you wouldn't have to copy s, because it's already copied. I suppose this is involuntarily, so you might want to read about how to pass objects to functions and how to return objects from function in C++.

The problem you're reporting, though, hints at your copy constructor not working properly. Did you implement the copy constructor or are you using the compiler-supplied one?

回梦 2024-10-05 09:48:05

这可能取决于 Set 的实现方式。如果赋值运算符和复制构造函数尚未重载以执行深层复制(包括元素),那么它将无法按预期工作。

This probably depends on how Set is implemented. If the assignment operator and the copy constructor haven't been overloaded to do a deep copy(including elements) then it won't work as expected.

-小熊_ 2024-10-05 09:48:05

您是否为您的类实现了复制构造函数?
默认复制构造函数将复制类中的任何指针,但不会复制您指向的内容。您需要创建一个复制构造函数或重载“=”运算符。

Have you implemented a copy constructor for your class?
Default copy constructor will copy any pointer in your class, but not the content you are pointing to. You need to create a copy constructor or overload the '=' operator.

舞袖。长 2024-10-05 09:48:05

我会完全避免使用 char 指针并使用 std::string 代替。这样你甚至不需要复制构造函数和赋值运算符,因为生成一次的编译器就可以了。 (因为“Set”类的“元素”是可复制构造的并且具有赋值运算符)
这是我的解决方案:

#include <iostream>
#include <string>

class Set{
  std::string elements;

  public:
         Set() {
             elements = "";
         }

         explicit Set(char* _elements) {
             if (_elements)
                elements = _elements;
         }

         Set operator+(const Set& s){
             Set temp(*this);    

             temp.elements += s.elements;
             return temp;
         }



};

顺便说一句。我从 char* 添加了一个构造函数,以便可以以某种方式从外部初始化“元素”。不确定这是否是您想要的。

I would avoid a char pointer completely and use std::string instead. This way you dont even need a copy constructor and an assigment operator because the compiler generated once will do just fine. (because 'elements' of the 'Set' class is copy-constructible and has an assignment operator)
Here is my solution:

#include <iostream>
#include <string>

class Set{
  std::string elements;

  public:
         Set() {
             elements = "";
         }

         explicit Set(char* _elements) {
             if (_elements)
                elements = _elements;
         }

         Set operator+(const Set& s){
             Set temp(*this);    

             temp.elements += s.elements;
             return temp;
         }



};

Btw. I added a constructor from char* so that 'elements' can somehow be initialized from outside. Not sure if this is what you wanted.

本宫微胖 2024-10-05 09:48:05

好的。我遵循了三法则并做了以下更改...你能指出这有什么问题吗?

#include<iostream>
#include<cstring>

using namespace std;

class Set{
  char *elements;

  public:
         Set() {
              elements = new char('\0');
              index = -1;
         }

         Set(const Set& cpy){
                  *this = cpy;
         }


         Set operator+(Set s){
             Set temp = *this;       // IMPORTANT! copy constructor of Set is called, "this" is passed as argument
                                     // * = current OBJECT, else returns ADDRESS of current object

             for(int i=0; s.elements[i] != '\0'; i++){
                     temp(s.elements[i]);
             }

             return temp;

         }
         Set& operator=(Set s){  
              delete [] elements;
             elements = new char[strlen(s.elements) + 1];
             strcpy(elements,  s.elements); //overrides element of "this"

             return *this;
         }

    };

Ok. I went through rule of three and did the following changes... Can you point out what's wrong with this?

#include<iostream>
#include<cstring>

using namespace std;

class Set{
  char *elements;

  public:
         Set() {
              elements = new char('\0');
              index = -1;
         }

         Set(const Set& cpy){
                  *this = cpy;
         }


         Set operator+(Set s){
             Set temp = *this;       // IMPORTANT! copy constructor of Set is called, "this" is passed as argument
                                     // * = current OBJECT, else returns ADDRESS of current object

             for(int i=0; s.elements[i] != '\0'; i++){
                     temp(s.elements[i]);
             }

             return temp;

         }
         Set& operator=(Set s){  
              delete [] elements;
             elements = new char[strlen(s.elements) + 1];
             strcpy(elements,  s.elements); //overrides element of "this"

             return *this;
         }

    };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文