我在 C 遗留代码中使用了两个大型 C 结构,我需要从一个转换为另一个,然后反过来。像这样:
#include <iostream>
struct A {
int a;
float b;
};
struct B {
char a;
int b;
};
struct C {
A a;
B b;
};
struct D {
int a;
char b;
float c;
};
void CtoD( const C& c, D &d ) {
d.a = c.a.a;
d.b = c.b.a;
d.c = c.a.b;
}
void DtoC( const D &d, C& c ) {
c.a.a = d.a;
c.b.a = d.b;
c.a.b = d.c;
}
int main()
{
C c = { { 1, 3.3f }, { 'a', 4 } };
D d = { 1, 'b', 5.5f };
#if 0
CtoD( c, d );
#else
DtoC( d, c );
#endif
std::cout<<"C="<<c.a.a<<" "<<c.a.b<<" "<<c.b.a<<" "<<c.b.b<<std::endl;
std::cout<<"D="<<d.a<<" "<<d.b<<" "<<d.c<<std::endl;
}
函数 CtoD
和 DtoC
做同样的事情,但方向相反。更改一种结构需要同时更改它们。
为了尽量减少出错的可能性并避免重复,我想实现某种映射,我只定义一次连接,然后将一个值复制到另一个值。这样,如果结构发生变化,则只需要进行一次更改。
那么,问题是:怎么做?是否有我可以使用的设计模式?
我的真实结构有数百个字段。以上只是简化的例子。
最佳答案
在您的文字示例中,我认为不值得麻烦。只需编写测试即可确保您的转换工作顺利。
在你的真实代码中,如果你的结构有“数百个字段”,你的结构可能设计得很糟糕。也许它们应该由更小的物体组成。我从来没有设计过任何需要完全相同的结构对象中的数百个字段的东西 - 相反,这些字段允许某种分类,以便它们可以在更小的串中进行处理。
由于您的代码是遗留并且您不想重写它,只需为您的转换函数编写测试,正如我在上面的示例中所说的那样。
经过良好测试的代码不再是遗留代码。遗留代码基本上是您没有对其进行自动化测试的代码。
如果重写它不是一个选项,那么测试它是必须的。
关于“双向”测试的成本,Idan Arye 的 comment below说明一切:
Since the conversion is symmetric, testing it both ways is not that much more work than testing it one way. All you need to do is init two structs -
C c
andD d
- and set them to be the converted versions of each other. Then you just have to check thatCtoD(c)==d
andDtoC(d)==c
(or use comparison functions if you happen to have them defined). The big work here is initializingc
andd
- but you would have to do that anyways if you wanted to test one way conversion, so adding the test for the other way is very cheap.
关于c++ - 如何在不重复代码的情况下统一实现双向转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19377612/