开发者

How to reassign `this` pointer inside object member function?

I have an interesting question about C++ pointers.

You probably will think that I have to change my design, and avoid doing what I am doing, and you are probably right. But let's assume that I have a good reason to do it my way.

So this is the situation. I have a C++ class TestClass, and I have a pointer A of this type:

TestClass* A = new TestClass();

A开发者_StackOverflowmong other things TestClass has this function:

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

This function creates object B of the same type and populates it with some data.

At the end of this function, I want pointer A to point at object B. Anywhere outside this function it would look like A=B; inside this function it could look like this = B

But as you know you cannot reassign "this" pointer.

Possible solutions:

  1. Copy the memory:

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

    This method works correctly. The function copies each bit of object B into object A.

    Problem: if TestClass is a big object(and it is), it creates significant overhead in performance for multiple Foo calls.

  2. Return a B pointer from the function and do something like this

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

    But this code looks stupid, and it makes function Foo very hard to use.

So the question is, how I can do this = B from inside a member function, without copying whole objects?


Use an extra level of indirection. Your TestClass can have a pointer that points to a class that contains all of its data.

class TestClass
{
private:
  TestClassData* m_data;

};

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

Just make sure your operator== returns true if the contents of m_data are equal.


how i can do this = B

You cannot.

One of the working solutions: memcpy(this, B, sizeof(TestClass)); this method working correctly.

If TestClass is not a POD, this function doesn't work. You can't memcpy objects with virtual functions, for example. You'll blow away the vtable.


Inside of your function, you can do

*this = B;

Which make pretty the same copy operation.
Or you could also declare

Foo(TestClass &X);

And reassign X address inside.


You can't. this is defined by the standard as a TestClass * const.

To realize why, think about this code:

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

A is on the stack. How do you make an object on the stack 'refer' to something else?


The problem is that many pointers, not just A, can point to the old object. The this pointer is not A, although A contains a copy of it. The only way to do it is 1. reassign A, or 2. make a new pointer type that adds a level of indirection to your object so you can replace it without anyone knowing.


What you are doing is not good.

First off, you have function Foo that will:

  • Create and generate a new class
  • Reassign an existing class to the new class

So, why not just change the existing class into the class you want?

That said, you could make Foo static and take "take this manually":

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

But that's equally nasty as your other solutions. We probably need more context to give you the best solution.


I'm pretty sure that you should look at smart pointers as a way to solve this problem. These essentially add an extra level of indirection (without changing the syntax clients use), and would allow you so change the actual object pointed to without informing the client.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜