我有一个关于C ++指针的有趣问题。
你可能会认为我必须改变我的设计,并避免 做我正在做的事情,你可能是对的。 但是我们假设我有充分的理由按照自己的方式去做。
所以情况就是如此。我有一个C ++类TestClass,我有一个这种类型的指针A:
TestClass* A = new TestClass();
TestClass除此之外还有这个功能:
void TestClass::Foo(){
TestClass* B = new TestClass();
...
}
此函数创建相同类型的对象B,并用一些数据填充它。
在此函数结束时,我希望指针A指向对象B.
在此功能之外的任何地方,它看起来像 A=B
;在这个功能里面
它可能看起来像 this = B
但是如你所知,你不能重新分配“这个”指针。
可能的解决方案:
复制内存:
memcpy(this, B, sizeof(TestClass));
此方法可正常工作。该函数将对象B的每个位复制到对象A中 问题:如果TestClass是一个大对象(它是),它会为多个Foo调用的性能带来很大的开销。
从函数返回一个B指针并执行类似这样的操作
Temp = A;
A=A->Foo();
freeMemory(Temp);
但是这段代码看起来很愚蠢,而且它使得函数Foo很难使用。
所以问题是,如何在成员函数中执行 this = B
而不复制整个对象?
答案 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)
我很确定您应该将智能指针作为解决此问题的方法。这些本质上添加了额外的间接级别(不改变客户端使用的语法),并允许您更改指向的实际对象而不通知客户端。