我正在学习 c++ 中的指针并且遇到了一些麻烦。我有一个Foo
在头文件中声明一些数据的类:
private:
const Bar *obj;
哪里Bar
有课。
然后在 c++ 实现中我想替换*obj
它,使其指向一个完全不同的Bar
对象。*obj
是恒定的,那么我如何更改*obj
指向的内容,或者更确切地说,更改内存中的内容*obj
?同样在Foo
的析构函数中,我该如何解除分配*obj
?
我正在学习 c++ 中的指针并且遇到了一些麻烦。我有一个Foo
在头文件中声明一些数据的类:
private:
const Bar *obj;
哪里Bar
有课。
然后在 c++ 实现中我想替换*obj
它,使其指向一个完全不同的Bar
对象。*obj
是恒定的,那么我如何更改*obj
指向的内容,或者更确切地说,更改内存中的内容*obj
?同样在Foo
的析构函数中,我该如何解除分配*obj
?
给定你的类定义
class A {
private:
const Bar *obj;
};
obj
是一个指向常量Bar
对象的指针。您可以更改该指针所指向的内容,但不能更改所指向对象的内容。
所以,如果你有一个新Bar
对象并且你想改变obj
它指向那个,你可以简单地分配新值:
/* New object: */
Bar *new_bar = new Bar;
/* Change the pointer: */
obj = new_bar;
然而,有两个问题。
如果新Bar
对象是在类之外创建的,则不能直接将其分配给它,obj
因为后者是私有的。因此,您需要一个 setter 函数:
class A {
private:
const Bar *obj;
public:
void set_obj(const Bar *new_obj) { obj = new_obj; }
};
您必须确定谁最终将拥有该Bar
对象,即谁负责释放它所占用的堆空间。如果调用者负责,那么您可以按上述方式对其进行编码,即class A
永远不会创建新Bar
对象,也不会删除任何对象。它只会维护一个指向Bar
在类之外创建和删除的对象的指针。
但是如果class A
上面确实负责Bar
对象占用的内存空间,则必须在析构函数中使用以释放空间,并且在分配delete obj
新对象时也必须释放空间。Bar
也就是set_obj
上面的函数需要改成这样:
void set_obj(const Bar *new_obj) { delete obj; obj = new_obj; }
否则你会有内存泄漏。在复制构造函数(除非你删除它)和赋值运算符中必须采取类似的措施:这两个函数在创建对象的副本class A
时都会使用,在这种情况下,你必须确保不要简单地复制指针,而是分配新空间并复制对象(即您必须执行深层复制):
A(const A& a):obj(new Bar(*a.obj)) {}
A& operator=(const A& a) { delete obj; obj = new Bar(*a.obj); return *this; }
话虽如此,如果您的类负责内存空间,那么使用智能指针类而不是原始指针会更好。主要原因是: (i) 上面比较复杂,容易出错;(ii) 上述情况仍然不是很好——当抛出异常时,可能仍然存在内存泄漏或更严重的问题,例如在Bar
. C++11 提供了一个名为 的智能指针类std::unique_ptr
,它似乎非常适合您的目的:
class A {
private:
std::unique_ptr<const Bar> obj;
public:
~A() {}
void set_obj(std::unique_ptr<const Bar> new_obj) { obj = new_obj; }
};
有了这个,智能指针将处理需要自动释放的任何内存空间,无论是在销毁时还是在将新Bar
对象分配给指针时。
您不能使用该指针来更改所指向的值,这就是它是 const 的原因,但您应该能够更改它所指向的内容。
在 c++ "const Bar *obj;" 意味着您有一个指向只读 Bar 对象的指针;这意味着您可以将其指向任何只读 Bar 对象。
您还可以指向一个非常量变量,从而保证您不会使用该指针更改它。
如果你想要一个指针,在某种意义上它是恒定的,它不能指向其他任何东西,那么你应该这样写:
Bar * const obj = some_object;
这将编译并正常工作:
const int p = 1, q = 2;
int r = 3;
const int* i = &p;
i = &q; // point it to a different const variable.
i = &r; // point it to a different non const variable.
正如所写,我相信这是一个指向 const Bar 对象的指针,而不是一个常量指针。