【问题标题】:Is it possible to dereference an object to another object inside his own method?是否可以在他自己的方法中将一个对象取消引用到另一个对象?
【发布时间】:2020-02-19 14:32:48
【问题描述】:

我有一个关于 C++ 问题的问题。假设我有一个非常大的班级,叫做BigClass,我说BigClass* foo = new BigClass();

假设我在 BigClass 中有一个方法,它定义了另一个 BigClass 类型的本地对象 tmp,在方法结束时,我通过使用 tmp 做一些事情来检查是否有错误,如果没有,我想要将this 取消引用到该对象。我不想将所有参数从tmp 复制到this,因为对象太大,过程会很慢。有没有办法在自己的方法中取消引用对象?

例子:

class BigClass
{
    int a;
    long b;
    std::vector<int> c;
    // other members...

    void replace()
    {
        BigClass* tmp = new BigClass();
        // do some calculations with tmp
        *this = tmp; // problem
    }
}

为什么 *this = tmp 是个问题?

我定义了一个 operator= 来做这样的事情:

this.a = src.a;
this.b = src.b;
this.c = src.c;
.
.
.

但是我复制了所有成员变量,这很慢。我想简单地取消引用对象而不是复制所有成员变量。

【问题讨论】:

  • 如果你不想复制,move它。虽然像this = new Bigclass() 这样的东西是非法的。
  • "有什么方法可以在对象自己的方法中取消引用?"不太清楚,你是在问你是否可以做*this?是的你可以。一些代码真的很有帮助
  • 如果你添加一个你正在尝试做的例子,我会投票支持重新开放
  • 我不想将所有参数从 tmp 复制到 this — 我假设您的意思是复制所有成员变量/子对象。那么为什么?你不抄袭的理由是什么?如果出于性能原因,您可以简单地移动它们,*this = std::move(tmp);

标签: c++ c++11 pointers copy dereference


【解决方案1】:

如果你不想复制,你可以移动它来代替:

struct BigClass {
    void func() {
        BigClass tmp;

        *this = std::move(tmp);
    }
};

移动操作通常不涉及动态分配或大缓冲区的复制。

如果您关注rule of zero,将为您定义移动赋值运算符。

否则,您始终可以使用默认运算符来定义它:

struct BigClass {
    BigClass& operator=(BigClass&&) = default;

    // ...
};

您也可以编写自己的运算符,但默认的运算符通常可以很好地完成这项工作。

struct BigClass {
    //          quite important ----v------v
    BigClass& operator=(BigClass&& rhs) noexcept {
        this->a = std::move(rhs.a);
        this->b = std::move(rhs.b);
        this->c = std::move(rhs.c);
    }

    // ...
};

移动操作通常非常快,比new 快得多。


或者,您也可以新建一个对象并为其分配指针:

struct BigClass {
    auto replace() -> BigClass* {
        auto tmp = new BigClass{};

        // ...

        return tmp;
    }
};

请注意,因为它涉及动态分配,因此速度要慢得多。

【讨论】:

  • 非常感谢这是一个非常有帮助的答案:)
  • @Delprof 除非必要,否则我会避免使用共享指针。最好是唯一的指针。
  • 我的问题是我使用的是 C++10 并且 move() 无法编译:D 所以我搜索了一些使用共享指针的解决方案
  • @Delprof 当然你可以转换为右值引用。 std::move 只是对右值的强制转换,没有别的。编写 move 实现并不那么具有挑战性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-16
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
相关资源
最近更新 更多