我在使用模板结构时遇到了一些麻烦。
template<typename T>
struct A{
const int v1;
T* v2;
};
我的目的是让v1
永远不可编辑,而v2
如果我使用T
则应该是可编辑的,如果我使用const T
作为类型则不可编辑。
如果我创建构造函数来初始化A
,则结构变为:
template<typename T>
struct A{
const int v1;
T* v2;
A() : v1(-1) { v2=NULL; }
A(int value) : v1(value) { v2=NULL; }
};
但是g ++说我需要一个特定的赋值运算符:
错误:非静态const成员'const int A :: v1',不能使用默认赋值运算符
但是我的赋值运算符也应该允许编辑v1
。我唯一想避免的是从外面进行编辑,例如:
A a;
a.v1=10;
有没有办法实现这个(没有创建getter / setter或使用指向具有所需值的新A(int)的指针)?
如果我将v1声明为const int *怎么办?它可能会某种程度上引用某些值,但它无法编辑它。
答案 0 :(得分:2)
它表示您无法使用默认赋值运算符。没有什么能阻止您编写自己的operator=
并使用const_cast
。不幸的是,这将是未定义的行为,因为v1
被声明为const。所以我建议您使用访问者和私有数据。
答案 1 :(得分:2)
这是一种“公开”可由类自己的成员函数(包括赋值)修改的公共只读数据成员的方法:
template <typename T>
class Helper {
friend class A;
T *ptr;
Helper &operator=(const Helper &rhs) = default; // in C++11
Helper &operator=(const Helper &rhs) { ptr = rhs.ptr; } // in C++03
public:
Helper(T *ptr) : ptr(ptr) {}
operator const int &() const { return *ptr; }
};
class A {
int v1_;
public:
Helper<int> v1;
A() : v1(&v1_) {} // although `A` should have a constructor that sets `v1_`
A(const A &rhs) { v1_ = rhs.v1_; v1 = Helper<int>(&v1_); }
A &operator=(const A &rhs) { v1_ = rhs.v1_; v1 = Helper<int>(&v1_); }
};
现在A类以外的任何人都可以使用v1
,但他们唯一可以使用它的方法是获得对const int&
的{{1}}引用。
给v1_
一个返回A
的getter函数要容易得多,但是如果你真的想要数据成员语法,那么这就提供了它......
答案 2 :(得分:1)
你可以把它变成一个公开所有类的类(这就是所有的结构)并使用初始化列表 - 不需要getter / setters
答案 3 :(得分:0)
我通过将v1的类型从int更改为const int *解决了我的问题,通过这样做,我可以更改v1的地址,从而更改v1指向的值,但阻止任何类型的编辑。
所以,这是我的新简单结构
template<typename T>
struct A{
const int* v1;
T* v2;
};
当我使用A类型为T时,我让v2进行编辑,当我使用类型为T const的A时,我会阻止任何编辑v2指向值的尝试。