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
Possible solutions:
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.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.
精彩评论