C++私有常量指针

3

我正在学习C++中的指针,遇到了一些问题。 我有一个类Foo,在头文件中声明了一些数据:

private:
const Bar *obj;

这里的Bar是一个类。

然后在C++实现中,我想要替换*obj,使其指向完全不同的Bar对象。由于*obj是常量,因此我如何更改*obj指向的内容或者说,内存中的*obj中的内容?此外,在Foo的析构函数中,我该如何释放*obj


你想要替换 *obj,使其指向一个完全不同的 Bar 对象。我不确定我理解这意味着什么。你是想让 obj 指向另一个 Bar 对象(这没问题),还是想要更改 obj 当前所指向对象的内容(由于 const 不可能实现)? - jogojapan
是的,我希望 obj 指向一个新的 Bar - Flynn
4个回答

4
给定您的类定义
class A {
private:
  const Bar *obj;
};

obj是指向常量Bar对象的指针。您可以更改该指针指向的内容,但无法更改所指向的对象的内容。

因此,如果您有一个新的Bar对象,并且想要更改obj以使其指向该对象,您只需分配新值即可:

/* New object: */
Bar *new_bar = new Bar;
/* Change the pointer: */
obj = new_bar;

然而,有两个问题。

  1. If the new Bar object is created outside the class, you cannot directly assign it to obj because the latter is private. Hence you need a setter function:

    class A {
    private:
      const Bar *obj;
    public:
      void set_obj(const Bar *new_obj) { obj = new_obj; }
    };
    
  2. You must determine who will eventually own the Bar object, i.e. who is responsible for freeing the heap space it takes. If the caller is responsible then you can code it as above, i.e. class A will never create new Bar objects, nor delete any. It will just maintain a pointer to Bar objects created and deleted outside the class.

    But if class A above is actually responsible for the memory space taken by the Bar objects, you must use delete obj in the destructor to free the space, and you must also free the space when you get a new Bar object assigned. That is, the set_obj function above needs to be changed to this:

    void set_obj(const Bar *new_obj) { delete obj; obj = new_obj; }
    

    Otherwise you'll have a memory leak. Similar measures must be taken in the copy constructor (unless you delete it), as well as the assignment operator: Both functions are used whenever a copy of a class A object is made, and in that case you must make sure that you do not simply copy the pointer, but instead allocate fresh space and copy the object (i.e. you must perform a deep copy):

    A(const A& a):obj(new Bar(*a.obj)) {}
    A& operator=(const A& a) { delete obj; obj = new Bar(*a.obj); return *this; }
    

    Having said this, if your class is responsible for the memory space, it is a much better idea to use a smart pointer class instead of a raw pointer. The main reasons are: (i) The above is quite complicated and it's easy to make mistakes; (ii) The above is still not very good – there may still be memory leaks or worse problems when an exception is thrown, e.g. in the constructor of Bar. C++11 provides a smart pointer class called std::unique_ptr, which seems ideal for your purposes:

    class A {
    private:
      std::unique_ptr<const Bar> obj;
    public:
      ~A() {}
      void set_obj(std::unique_ptr<const Bar> new_obj) { obj = new_obj; }
    };
    

    With this in place, the smart pointer will take care of any memory space that needs to be freed automatically, both at destruction time as well as when a new Bar object is assigned to the pointer.


1
在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.

1

您不能使用该指针来更改被指向的值,这就是为什么它是一个const,但您应该能够更改它所指向的内容。


0

根据所写,我相信这是一个指向常量 Bar 对象的指针,而不是一个常量指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接