我说的是几十个成员,所以我真的会避免像创建一个一一复制所有内容的转换函数这样的事情。
4 回答
最好的办法是完全没有这种冗余来解决问题。这不是DRY。
我确信你不能应用的一个简单的解决方案(否则你已经这样做了),就是将这两种类型的通用语法移到一个基类中,并将语义差异分成两个派生(可能是空的)类。
如果这无法实现,您可以使用适配器类来封装您拥有的两种类型中的任何一种,并使用相同的接口访问它们。
Obj2 o2;
Adapter<Obj2> a(o2);
a.getFirstMember();
将指向一个对象的指针重新解释为指向另一个对象的指针也是可能的:
Obj1 *p = reinterpret_cast<Obj1 *>(&obj2);
但是这两个对象确实需要具有相同的内存占用,例如,对于在两种类型中复制的任何成员的任何可能值,以下必须始终为真:
memcmp(&obj1, &obj2, sizeof(Obj1)) == 0 && sizeof(obj1) == sizeof(obj2)
这通常很难保证,如果编译器会在两个类之一中为您添加一些东西,它可能会变得更加重要(几个月后的无辜重构可能很容易带来这个问题)。
例如考虑一个虚拟析构函数。如果您将它放在一个类中(作为唯一的虚拟成员)而不放在另一个类中,则该类将 avptr
作为其第一个成员,而另一个则没有,因此在两个类中访问该偏移量将产生不同的结果。
- 您不应该有两个具有完全相同成员但名称不同的数据类型。这只是冗余代码,尝试摆脱冗余类型。
- 如果由于某种原因你不能(真的很难相信你不能)简单地使用
reinterpret_cast
将一种类型转换为另一种类型。
请注意,类/结构需要与其组成完全相同,并且没有任何虚拟成员。
使用关键字联合。它不脆。
在使用 D3D11X 库项目和 DirectX10 编写游戏引擎时,我遇到了这个需求。例如,如果您有一个向量(3 个浮点数)并且您不想将其强制转换为 D3D11X_vector 或 DX11_vector 或其他任何内容,则可以创建一个两者结合的结构。(有时,对于图形驱动程序,代码不是您的,您无法更改样板以下的任何内容。)
不,没有其他方法可以从一个到另一个创建一个函数,无论如何这是最合乎逻辑的事情。也许您可以编写一个以某种方式遍历字段的宏……但是重点是什么?这只会使代码更加不稳定且难以理解。如果每个字段的类型完全相同并且它们的顺序相同,那么也许您可以从一个字段转换到另一个字段,但我仍然会避免这种情况。