3

我正在学习 c++ 中的指针并且遇到了一些麻烦。我有一个Foo在头文件中声明一些数据的类:

private:
const Bar *obj;

哪里Bar有课。

然后在 c++ 实现中我想替换*obj它,使其指向一个完全不同的Bar对象。*obj是恒定的,那么我如何更改*obj指向的内容,或者更确切地说,更改内存中的内容*obj?同样在Foo的析构函数中,我该如何解除分配*obj

4

4 回答 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. 如果新Bar对象是在类之外创建的,则不能直接将其分配给它,obj因为后者是私有的。因此,您需要一个 setter 函数:

    class A {
    private:
      const Bar *obj;
    public:
      void set_obj(const Bar *new_obj) { obj = new_obj; }
    };
    
  2. 您必须确定谁最终将拥有该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对象分配给指针时。

于 2012-10-24T01:15:14.877 回答
1

您不能使用该指针来更改所指向的值,这就是它是 const 的原因,但您应该能够更改它所指向的内容。

于 2012-10-24T00:53:27.140 回答
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.
于 2012-10-24T01:00:14.170 回答
0

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

于 2012-10-24T00:56:39.267 回答