我目前正在实现一个系统,其中包含许多表示客户端,业务,产品等对象的类。标准业务逻辑。正如人们所期望的,每个班级都有许多标准属性。当属性名称在运行时未知时,通过属性对C++对象进行通用聚合
我有基本相同的需求,如一个长长的清单:
- 检索所有企业的,其产业制造能力。
- 检索总部设在伦敦
类业务的所有客户端的能力,具有行业属性和客户端具有属性的位置。很明显,这是一个关系问题,在伪SQL中看起来像这样:
SELECT ALL business in business' WHERE sector == manufacturing
不幸的是,插入数据库不是一个选项。
我想要做的是有一个通用聚合函数,其签名将采取以下形式:
vector<generic> genericAggregation(class, attribute, value);
凡类是类对象的我想要聚合,属性和值作为类属性,价值感兴趣。在我的例子中,我把矢量作为返回类型,但这不起作用。可能更好地声明相关类类型的向量并将其作为参数传递。但这不是主要问题。
如何接受字符串形式的类,属性和值的参数,然后将这些参数映射到通用对象聚合函数中?
由于无法发布代码是不礼貌的,下面是一个虚拟程序,它创建了一群具有想象力的命名类的对象。包括一个特定的聚合函数,它返回一个B对象的向量,其A对象等于在命令行指定的id,例如..
$ ./aggregations 5
返回所有B的,其a对象 '我' 属性等于5请看下图:
#include <iostream>
#include <cstring>
#include <sstream>
#include <vector>
using namespace std;
//First imaginativly names dummy class
class A {
private:
int i;
double d;
string s;
public:
A(){}
A(int i, double d, string s) {
this->i = i;
this->d = d;
this->s = s;
}
~A(){}
int getInt() {return i;}
double getDouble() {return d;}
string getString() {return s;}
};
//second imaginativly named dummy class
class B {
private:
int i;
double d;
string s;
A *a;
public:
B(int i, double d, string s, A *a) {
this->i = i;
this->d = d;
this->s = s;
this->a = a;
}
~B(){}
int getInt() {return i;}
double getDouble() {return d;}
string getString() {return s;}
A* getA() {return a;}
};
//Containers for dummy class objects
vector<A> a_vec (10);
vector<B> b_vec;//100
//Util function, not important..
string int2string(int number) {
stringstream ss;
ss << number;
return ss.str();
}
//Example function that returns a new vector containing on B objects
//whose A object i attribute is equal to 'id'
vector<B> getBbyA(int id) {
vector<B> result;
for(int i = 0; i < b_vec.size(); i++) {
if(b_vec.at(i).getA()->getInt() == id) {
result.push_back(b_vec.at(i));
}
}
return result;
}
int main(int argc, char** argv) {
//Create some A's and B's, each B has an A...
//Each of the 10 A's are associated with 10 B's.
for(int i = 0; i < 10; ++i) {
A a(i, (double)i, int2string(i));
a_vec.at(i) = a;
for(int j = 0; j < 10; j++) {
B b((i * 10) + j, (double)j, int2string(i), &a_vec.at(i));
b_vec.push_back(b);
}
}
//Got some objects so lets do some aggregation
//Call example aggregation function to return all B objects
//whose A object has i attribute equal to argv[1]
vector<B> result = getBbyA(atoi(argv[1]));
//If some B's were found print them, else don't...
if(result.size() != 0) {
for(int i = 0; i < result.size(); i++) {
cout << result.at(i).getInt() << " " << result.at(i).getA()->getInt() << endl;
}
}
else {
cout << "No B's had A's with attribute i equal to " << argv[1] << endl;
}
return 0;
}
编译:
g++ -o aggregations aggregations.cpp
如果你想:)
而不是实现一个单独的聚合函数(即在例子中的getBbyA())我想有一个单一的通用聚合fu它考虑了所有可能的类属性对,从而满足所有的聚合要求。并且在稍后添加附加属性或额外的聚合要求的情况下,将自动考虑这些要求。
所以这里有一些问题,但我正在寻求洞察的主要问题是如何将运行时参数映射到类属性。
我希望我已经提供了足够的细节来充分描述我想要做的事情......
支持你能修改这些类吗? (如果你不行,你会遇到麻烦。) – Beta 2010-05-09 15:05:37
@Beta:不一定,人们也可以想到为这些访问定义的函数对象。有很多可能性。 – 2010-05-09 17:56:50
@Matthieu M .:我不明白。我可以只想两种方法来做到这一点,而无需为每个类的每个字段编写单独的例程:1)修改类或2)使用宏[shudder]。我很乐意学习另一种方法... – Beta 2010-05-09 18:51:25