我想以这种方式分离的原因 - 数据从无到有,方法可以有一百个依赖。所有依赖数据的人都不应该依赖于方法依赖。
我想做类似的事情:
//s_class_name.h
struct structName
{
data m_data
}
//class_name.h
class className : public structName
{
public:
void method(arg1, arg2, arg3, ..., argN); //using m_data
}
static_cast<className *>(&structNameObject)->method(arg1, arg2, arg3, ..., argN);
我看到两个问题:
1)打开所有数据访问。我想打开所有使用struct操作但不使用class的数据。
2)静态投射向下转换未定义。
你能解释一下,如何更好地实现模式数据和逻辑分离?
UPD:我有另一个想法,但我无法解释为什么它不好: 1)在s_class_name.h中,我可以声明模板方法
2)在class_name.h中,我可以实例化模板args。
答案 0 :(得分:1)
避免使用数据形成未经授权访问的一种方法是保护数据:只有从数据结构继承的类才能访问它:
class structName
{
protected: // only classes inheriting from this structure can access the data
data m_data;
};
然后,从数据结构继承的类可以根据需要使用数据:
class className : public structName
{
public:
void method(int arg1) { //using m_data
for (int i = 0; i < arg1; i++)
cout << i << ":" << m_data << endl;
}
};
你可以做以下事情:
className c; // if your object was a class before
structName*d=&c;
static_cast<className *>(d)->method(10); // you can downcast
// if your object wasn't a class before, it's UB, but it could probably work if your class has not virtuals and no own data.
1)数据与逻辑的分离不允许对象封装。
2)数据的初始化必须由派生类完成。这意味着您必须处理系统的显式初始化,因为没有其他方法可以确保数据的一致性。
3)您可以将类链接到错误的数据结构。
4)一旦类继承自数据结构,任何其他类都可以从类继承,从而结束设计。
5)数据不依赖于任何事物的基本假设可能被证明是错误的。您提供的方法可能需要私有数据(例如,保存小计,以及您可能为了性能目的而保留的其他重新规范的冗余数据),这些数据与数据紧密相关。因此,数据还取决于您实现的方法。
6)您的结构无法正确实现多态和继承:如果您有一个继承自dStructName
的数据结构StructName
,那么您还需要一个dclassName
派生的来自className
。但是dclassName
已经从StructName
继承......所以它将是一个非常微妙的问题需要解决,而传统的面向对象设计(将数据+方法封装成有意义的对象)它是一块蛋糕。
改进的方法是使用合成,因为你不能说className
是 structName
,但你可以假装className
有 structName
。
然后设计看起来有点像代理模式,提供另一个对象的代理来控制对它的访问(GoF)或装饰器,这取决于你如何看待它。
struct structName { data m_data; };
class className {
private:
structName *data; // access to your data object
public:
className(structName *d) : data(d) {} // constructor
void method(int arg1) { //using m_data
cout << data->m_data << endl;
}
};
以下是一些可能的用途:
structName d;
className cn(&d); // creating an object
cn.method(10); // using methods on the data
className(&d).method(3); // throw away temporary object destroyed when expression is evaluated.
// so no need for down-casting anymore.
通过这种设计,弱点1,4和6消失。这种方法是理想的,例如,如果您的结构数据是按需从数据库上传的。