Class classname
{
int member1;
int member2;
...
int membern;
public:
void setmember1(int);
void setmember2(int);
...
void setmembern(int);
void getmember1(int);
void getmember2(int);
...
void getmembern(int);
}
我知道我可以定义 2n 类函数来为上面的声明获取和设置 n指定的成员值。
然而,当 n 很大时,这似乎是不必要的乏味。有没有一种很好的方法来定义一个类函数,该函数需要额外的参数来设置/获取类的任何成员?
修改 除了语法错误之外,我对大型 n 的理由是保留课程背后的科学框架。例如,假设该类是酶。所以除非绝对必要,否则我宁愿将其属性保留在同一个地方,而不是按编号索引。
Set / get函数是公共的,因为它们是在另一个类(设置GUI)中调用的。
并且,不,并非所有成员都是整体。为了简单起见,我复制了意大利面。
答案 0 :(得分:4)
在实际代码中,您不应该拥有包含许多数据成员的类,当然也不能单独设置和获取可用的类。
你可以实现你要求使用数组的目的:
class classname
{
public:
setMemberDangerously(size_t index, int value) { data[index] = value; }
setMember(size_t index, int value)
{
if (! index < size) throw std::out_of_range("Index out of bounds");
data[index] = value;
}
private:
int data[N];
};
但是现在你的类看起来像一个集合,在这种情况下你也可以使用一个标准的库容器。
答案 1 :(得分:3)
或者:
修改强>
除了你的get
应
int getX() const;
修改强>
考虑另外两种可能性
[]
运算符std::vector
答案 2 :(得分:1)
您可以发明任何工具,使您设计糟糕的课程“几乎可以管理”。如果写入getter / setter很难,请不要这样做。您的课程必须是refactored。
此处的一般解决方案是 避免使用n
设计您的课程以保留single responsibility principle。避免使用god-classes。
答案 3 :(得分:0)
您触及了C ++的一个老问题,这是语言中非常有限的反射功能。如果您来自使用反射的语言,则下面的讨论值得一看:
How can I add reflection to a C++ application?
至于实用的建议,这里给出的所有其他答案都是完全合理的。
答案 4 :(得分:0)
我对setter / getter并不好玩,尽管它们在GUI等应用程序中很常见。无论如何,我有一个通用的解决方案,需要一个库,可能是一个矫枉过正的问题。假设您有以下类
class A
{
char member1;
int member2;
double membern;
public:
void set_member1(char c) { member1 = c; }
void set_member2(int i) { member2 = i; }
void set_membern(double d) { membern = d; }
char get_member1() { return member1; }
int get_member2() { return member2; }
double get_membern() { return membern; }
};
然后你可以写
auto val = _('c', 42, 3.14);
auto set = _(&A::set_member1, &A::set_member2, &A::set_membern);
auto get = _(&A::get_member1, &A::get_member2, &A::get_membern);
A a;
(a ->* set)(val);
cout << (a ->* get)() << endl;
打印
(c, 42, 3.14)
也就是说,你正在使用元组。语法_(...)
代表一个元组; val
是一个值元组(可能是不同类型),set/get
是指向成员的元组指针。上面给出的语法中的运算符->*
允许在具有多个参数的单个对象上调用多个成员函数,每个函数一个参数。调用get
的结果再次是一个值元组。
要使所有这些工作,您需要我正在开发的库ivl。上面的语法只是一个小样本;库更灵活,允许为标量定义函数或运算符,然后以元组或数组的形式,以任意组合方式调用它们。所有C ++运算符都被重载以允许这种“向量化”。除了指向成员的指针之外,运算符->*
还可以使用函数对象,以便内联调用。它还允许使用替代语法
a ->* set._(val);
cout << a ->* get._() << endl;
使成员函数在应用于对象之前首先与参数绑定。成员函数可以包含任意数量的(任何类型的)参数,但是在一次调用中所有参数都应该具有相同数量的参数。