如何在对象成员函数内重新分配`this`指针?

时间:2010-01-12 15:28:30

标签: c++ pointers this

我有一个关于C ++指针的有趣问题。

你可能会认为我必须改变我的设计,并避免 做我正在做的事情,你可能是对的。 但是我们假设我有充分的理由按照自己的方式去做。

所以情况就是如此。我有一个C ++类TestClass,我有一个这种类型的指针A:

TestClass* A = new TestClass();

TestClass除此之外还有这个功能:

void TestClass::Foo(){
    TestClass* B = new TestClass();
    ...
}

此函数创建相同类型的对象B,并用一些数据填充它。

在此函数结束时,我希望指针A指向对象B. 在此功能之外的任何地方,它看起来像 A=B ;在这个功能里面 它可能看起来像 this = B
但是如你所知,你不能重新分配“这个”指针。

可能的解决方案:

  1. 复制内存:

    memcpy(this, B, sizeof(TestClass));
    

    此方法可正常工作。该函数将对象B的每个位复制到对象A中 问题:如果TestClass是一个大对象(它是),它会为多个Foo调用的性能带来很大的开销。

  2. 从函数返回一个B指针并执行类似这样的操作

    Temp = A;
    A=A->Foo();
    freeMemory(Temp);
    

    但是这段代码看起来很愚蠢,而且它使得函数Foo很难使用。

  3. 所以问题是,如何在成员函数中执行 this = B 而不复制整个对象?

7 个答案:

答案 0 :(得分:13)

使用额外级别的间接。您的TestClass可以有一个指向包含其所有数据的类的指针。

class TestClass
{
private:
  TestClassData* m_data;

};

void TestClass::Foo()
{
  TestClassData* B = new TestClassData();
  ... 
  delete m_data;
  m_data = B;
} 

如果m_data的内容相等,请确保operator==返回true。

答案 1 :(得分:7)

  

我怎么能做到这一点= B

你不能。

  

其中一个有效的解决方案:   memcpy(this,B,sizeof(TestClass));   这种方法正常工作。

如果TestClass不是POD,则此功能不起作用。例如,您无法使用虚函数记忆对象。你会吹掉vtable。

答案 2 :(得分:6)

在你的功能中,你可以做到

*this = B;

进行相同的复制操作 或者您也可以声明

Foo(TestClass &X);

并在内部重新分配X地址。

答案 3 :(得分:4)

你做不到。 this由标准定义为TestClass * const

要明白原因,请考虑一下这段代码:

int main() {
   TestClass A;
   A.Foo();
   return 0;
}

A在堆栈中。如何让堆栈中的对象“引用”其他东西?

答案 4 :(得分:2)

问题是许多指针,而不仅仅是A,可以指向旧对象。尽管A包含它的副本,但该指针不是A.唯一的方法是1.重新分配A,或者2.创建一个新的指针类型,为你的对象增加一个间接级别,这样你就可以在没有人知道的情况下替换它。

答案 5 :(得分:1)

你在做什么并不好。

首先,你有一个函数Foo

  • 创建并生成新课程
  • 将现有班级重新分配给新班级

那么,为什么不将现有的课程改为你想要的课程呢?

也就是说,您可以将Foo设为静态,然后“手动”this

void Foo(TestClass*& this)
{
    delete this;
    this = // ...
}

但这与你的其他解决方案一样令人讨厌。我们可能需要更多上下文来为您提供最佳解决方案。

答案 6 :(得分:0)

我很确定您应该将智能指针作为解决此问题的方法。这些本质上添加了额外的间接级别(不改变客户端使用的语法),并允许您更改指向的实际对象而不通知客户端。