在 C++ 中,如果成员指针指向某个数据,如何保护该数据不被修改

In c++, if a member pointer point to some data, how to protect that data from being modified?

本文关键字:数据 何保护 保护 修改 如果 C++ 成员 指针      更新时间:2023-10-16
class A
{
public:
    A(){ val = 0; p = new int; *p = 0; }
    //void fun_1()const{ val = 1; }  not allowed
    void fun_2()const{ *p = 1; }
    void display()const{ cout<< val <<' '<< *p <<endl; }
private:
    int val;
    int * p;
};
int main()
{
    const A a;
    a.fun_2();
}

不允许更改 const 成员函数中的成员数据,例如 fun_1()const。但是,当数据不是直接的对象成员,而是分配存储并在对象内部分配时,const 函数无法保护它。 fun_2()const可以更改p指向的数据,尽管例如它是一个 const 函数。

有没有办法保护p指向的数据?

让编译器保护指向的对象相对简单,但这不会自动完成,因为它并不总是正确的做法。

template<typename T>
class constinator_ptr
{
    T* p;
public:
    explicit constinator_ptr( T* p_init ) : p (p_init) {}
    T*& ptr() { return p; } // use this to reassign, or also define operator=(T*)
    T* operator->() { return p; }
    const T* operator->() const { return p; }
    T& operator*() { return *p; }
    const T& operator*() const { return *p; }
};

只需使用它代替原始指针,如下所示:

class A
{
public:
    A() : val{0}, p{new int(0)} {}
    //void fun_1()const{ val = 1; }  not allowed
    void fun_2()const{ *p = 1; } // now causes error
    void display()const{ cout<< val <<' '<< *p <<endl; }
private:
    int val;
    constinator_ptr<int> p;
};

一个简单而通用的解决方案是你自己的智能指针类,具有深度常量语义。只需将一个普通指针包装在 deepconst<T> 中,将const T* operator->() constconst T& operator*() const添加到通常的非 const 版本中,您就完成了。

只需编写成员函数,以便它们不允许调用方修改对象。只要指针是私有的,它指向的任何内容都只能由其他成员函数看到。如果不公开更改指向对象的成员函数,则类的用户无法更改该函数。

请注意,您可以将成员声明为"指向 const 的指针"(这与 const 指针不同(。

int const* p 是指向 const int 的指针(指针可以更改,但它指向的 int

不能(,而 int* const 是指向 int 的 const 指针(指针无法更改 - 它始终指向相同的 int,但该 int 的值可以更改(。当然,int const* const是指向常量整数的常量指针。指针和 int 都不能修改。

但是,这并不能真正帮助您强制执行"const 成员函数不应修改指向的对象,但非 const 成员函数可以"(因为指向 const int 的指针将始终指向 const int,即使从非 const 成员函数使用也是如此(

只需声明一个指向常量的指针:

const int * p;

void fun_2()const{ *p = 1; } // main.cpp:36: error: assignment of read-only  
                                // location ‘*(const int*)((const B*)this)->B::p’

在这种情况下,p 指向的整数根本无法更改,无论它是从 const 还是non-const函数体完成的。如果仍然希望仍然能够从成员函数更改 int 的值non-const则不得在类外部公开指针,将指针设为私有并相应地使用它。