采取这种虚拟结构:
struct foo
{
int* pI;
void bar() const
{
int* ptrToI = pI; // I want this to require 'const int*'
*ptrToI = 5; // I want this to fail
}
}__test__;
如何设计此结构以防止我更改pI指向的值?
答案 0 :(得分:1)
除非您可以创建成员const int*
,否则可以使用继承将成员隐藏在成为子类的内容中,并在基类中提供protected
函数,以生成const int*
}指针:
class base_foo
{
int* pI;
protected:
const int* get_pI(){return pI;}
};
struct foo : base_foo
{
int* ptrToI = get_pI(); // will fail due to attempted conversion to int*
/* and so on*/
另请注意,包含两个连续下划线的任何标记都是保留的,因此,正式地,程序的行为未定义:重命名__test__
。
答案 1 :(得分:1)
您可以使用自定义smart pointer
来隐藏基础指针:
template <typename T>
struct ptr_t
{
private:
T *ptr;
public:
//Constructors and assignment operators
ptr_t(): ptr(nullptr) {}
ptr_t(T* p): ptr(p) {}
ptr_t(const ptr_t &other): ptr(other.ptr) {}
ptr_t& operator=(T* p) {this->ptr=p;return *this;}
ptr_t& operator=(const ptr_t &other) {this->ptr=other.ptr; return *this;}
//Note that the smart pointers included in the standard returns non-const pointers
//That is why you need to define a custom smart pointer, which forces the const pointer return in the const version of the operators.
const T* operator->() const {return ptr;}
T* operator->() {return ptr;}
const T& operator&() const {return *ptr;}
T& operator&() {return *ptr;}
operator const T*() const {return ptr;}
operator T*() {return ptr;}
};
struct foo2
{
ptr_t<int> pI;
void nonconst_bar()
{
int* ptrToI = pI; // Now success, since not const
*ptrToI = 5;
}
void failing_bar() const
{
//int* ptrToI = pI; // This fails
//*pI = 5; // This also fails
}
void success_bar() const
{
const int* ptrToI = pI;
//*ptrToI = 5; // This is not possible anymore
}
};