继续我在这里提出的问题:C++ multi-dimensional data handling
在我的例子中:我有许多芯片,每个芯片有许多寄存器,每个寄存器有许多单元,每个单元有许多晶体管。我询问是否为它们使用一个复杂的STL容器,或者为它们实现完整的类。而且,按照建议,我选择为他们实现完整的课程。我有:
class Chip
{
map<RegisterLocation, Register> RegistersPerLocation;
};
class Register
{
map<CellLocation, Cell> CellsPerLocation;
};
// etc..
现在,我需要将数据填充到类中,我无法决定:读取数据是否应该由这些类负责,或者它们是否应该包装容器并且读取将在外部完成。
我的意思是我必须选择以下之一:或者:
class Chip
{
map<RegisterLocation, Register> RegistersPerLocation;
public:
void AddRegisterPerLocation(RegisterLocation, Register);
};
void ReadChipData(Chip & chip)
{
for (RegisterLocation loc = 0; loc < 10; loc++)
{
Register reg;
ReadReg(reg);
chip.AddRegisterPerLocation(loc, reg);
}
}
void ReadReg(Register & reg)
{
for (CellLocation loc = 0; loc < 10; loc++)
{
Cell cell;
ReadCell(cell);
reg.AddRegisterPerLocation(loc, cell);
}
}
//etc...
或者:
class Chip
{
map<RegisterLocation, Register> RegistersPerLocation;
public:
void ReadData();
};
void Chip::ReadData()
{
for (RegisterLocation loc = 0; loc < 10; loc++)
{
Register reg;
reg.ReadData();
RegistersPerLocation[loc] = reg;
}
}
//etc...
void ReadChipData(Chip & chip)
{
chip.ReadData();
}
谢谢。
答案 0 :(得分:2)
如果您正在考虑将读取器/写入器绑定到域对象以遵循封装原则,那么您在某种程度上是正确的。但请记住:您不仅绑定任何操作,还绑定有效行为。对于域中的对象有意义。
要记住的另一件事是分离关注点。可序列化不是Chip
的内在行为 - 对域对象进行建模将是不公平的IMO。 YMMV。
将阅读(和写作)与班级分开。正如图书馆那样。如果必须,请公开迭代器。你可以重载'&lt;&lt;&lt;和'&gt;&gt;'语法糖的运算符;)
课程上的一个小问题 - 基于模板的方法看起来很有希望。
这是我编写的一些代码:您也可以尝试以下代码。 (我已经在MS VS2005上成功编译并运行它,但是在你的系统上检查它。此外,有人可以修复标签 - 感觉懒得做到这一点:P)
/*+-----------8<----------------------------8<-----------+*/
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
#include <iterator>
/* mother template */
template<class _Item>
struct Hardware
{
Hardware() : _myCont(2 + ::rand() % 5) {}
private:
typename vector<_Item> _myCont;
// i/o friends
template<class _Item>
friend ostream& operator<<(ostream& output,
const Hardware<_Item>& me);
template<class _Item>
friend istream& operator>>(istream& in,
const Hardware<_Item>& me);
};
/* actual domain objects */
/* base object */
struct Transistor {
};
/* built objects */
typedef Hardware<Transistor> Cell;
typedef Hardware<Cell> Register;
typedef Hardware<Register> Chip;
/* poorman's introspection utility */
template<class T>
const char *who() { return ""; }
template<>
const char *who<Transistor>() { return "Transistor"; }
template<>
const char *who<Cell>() { return "Cell"; }
template<>
const char *who<Register>() { return "Register"; }
template<>
const char *who<Chip>() { return "Chip"; }
/* writer/serialize out */
template<class T>
ostream& operator<<(ostream& out, const Hardware<T>& hw) {
// whatever you need to do to write
// os << chip works fine, because you will provide a specialization
out << "[ " << ::who<Hardware<T>>() << " ]\n\t";
std::copy(hw._myCont.begin(), hw._myCont.end(),
std::ostream_iterator< T >(std::cout, "\n\t"));
return out;
}
/* specialize for base object */
ostream& operator<< (ostream& out, const Transistor& hw) {
out << "[ " << ::who<Transistor>() << " ]\n";
return out;
}
/* reader/serialize in */
template<class T>
istream& operator>>(istream& in, const Hardware<T>& hw) {
// whatever you need to do to read
// similarly in >> chip works fine,
return in;
}
// driver showing relationships
// Chip -> Register -> Cell -> Transistor
int main() {
Transistor t;
std::cout << t << std::endl;
Cell ce;
std::cout << ce << std::endl;
Register r;
std::cout << r << std::endl;
Chip C;
std::cout << C << std::endl;
}
/*+-----------8<----------------------------8<-----------+*/
警告:尚未测试,因此可能存在相当多的编译器错误/警告。但这应该让你知道我想说的是什么。
答案 1 :(得分:-1)
使类对其序列化负责更好 - 一旦更改了类字段,就必须更改相同的类序列化方法,而不是那些读取器/编写器代码。