Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;私有常量指针 我正在学习C++中的指针,而且遇到了一些麻烦。 我有一个类Foo,它在头文件中声明了一些数据: private: const Bar *obj;_C++ - Fatal编程技术网

C++;私有常量指针 我正在学习C++中的指针,而且遇到了一些麻烦。 我有一个类Foo,它在头文件中声明了一些数据: private: const Bar *obj;

C++;私有常量指针 我正在学习C++中的指针,而且遇到了一些麻烦。 我有一个类Foo,它在头文件中声明了一些数据: private: const Bar *obj;,c++,C++,其中,Bar是一个类 >在C++实现中,我想替换 *Obj> ,以便指向完全不同的 bar 对象>code>*obj是常量,那么如何更改*obj指向的内容,或者更确切地说,更改*obj的内存内容?同样在Foo的析构函数中,如何取消分配*obj?您不能使用该指针来更改指向的值,这就是为什么它是一个常量,但是你应该能够改变它指向的东西。< /P> < P>作为书面,我相信这是指向const bar对象而不是常数指针的指针。 C++上的const bar *Obj';“这意味着你有一个指向只读栏对

其中,
Bar
是一个类


<> >在C++实现中,我想替换<代码> *Obj> <代码>,以便指向完全不同的<代码> bar <代码>对象>code>*obj是常量,那么如何更改
*obj
指向的内容,或者更确切地说,更改
*obj
的内存内容?同样在
Foo
的析构函数中,如何取消分配
*obj

您不能使用该指针来更改指向的值,这就是为什么它是一个常量,但是你应该能够改变它指向的东西。< /P> < P>作为书面,我相信这是指向const bar对象而不是常数指针的指针。

C++上的const bar *Obj';“这意味着你有一个指向只读栏对象的指针;这意味着您可以将其指向任何只读条对象

您还可以指向一个非常量变量,从而保证不会使用该指针更改它

如果你想有一个指针,它在某种意义上是常量,不能指向其他任何东西,那么你应该这样写:

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.

根据你的类定义

class A {
private:
  const Bar *obj;
};
obj
是指向常量
Bar
对象的指针。可以更改指针指向的对象,但不能更改指向的对象的内容

因此,如果您有一个新的
Bar
对象,并且希望更改
obj
以使其指向该对象,您可以简单地分配新值:

/* New object: */
Bar *new_bar = new Bar;
/* Change the pointer: */
obj = new_bar;
然而,有两个问题

  • 如果新的
    对象是在类之外创建的,则不能直接将其分配给
    对象
    ,因为后者是私有的。因此,您需要一个setter函数:

    class A {
    private:
      const Bar *obj;
    public:
      void set_obj(const Bar *new_obj) { obj = new_obj; }
    };
    
  • 您必须确定谁将最终拥有
    对象
    ,即谁负责释放所占用的堆空间。如果调用方负有责任,则您可以按上述方式对其进行编码,即
    A类
    永远不会创建新的
    条形
    对象,也不会删除任何对象。它只会维护一个指向类外创建和删除的
    Bar
    对象的指针

    但是,如果上面的
    class A
    实际上负责
    Bar
    对象占用的内存空间,则必须使用析构函数中的
    delete obj
    来释放空间,并且在分配新的
    Bar
    对象时也必须释放空间。也就是说,上面的
    set_obj
    功能需要更改为:

    void set_obj(const Bar *new_obj) { delete obj; obj = new_obj; }
    
    否则,您将出现内存泄漏。复制构造函数(除非删除它)以及赋值运算符中必须采取类似的措施:每当创建
    a类
    对象的副本时,都会使用这两个函数,在这种情况下,您必须确保不只是复制指针,而是分配新空间并复制对象(即,您必须执行深度复制):

    话虽如此,如果您的类负责内存空间,那么使用智能指针类而不是原始指针是一个更好的主意。主要原因是:(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; }
    };
    
    A类{
    私人:
    std::唯一对象;
    公众:
    ~A(){}
    void set_obj(std::unique_ptr new_obj){obj=new_obj;}
    };
    
    在这个位置上,智能指针将处理需要自动释放的任何内存空间,无论是在销毁时,还是在为指针分配新的
    对象时


  • 您想替换
    *obj
    以便它指向一个完全不同的
    Bar
    对象。我不知道这是什么意思。您想让
    obj
    指向一个不同的
    Bar
    对象吗(这样做没问题),或者您想更改
    obj
    当前指向的对象的内容(由于
    const
    的原因,这是不可能的)?是的,我想
    obj
    指向一个新的
    class A {
    private:
      std::unique_ptr<const Bar> obj;
    public:
      ~A() {}
      void set_obj(std::unique_ptr<const Bar> new_obj) { obj = new_obj; }
    };