在图形中,所有几何数据类型都非常相似。为避免代码重复,但仍然对您正在做的事情有所了解,图形编码建议使用Vector
类,其中包含Points
,Normals
和Directions
的多个typedef。
因此,根据Normalize
函数的签名(正如其所写),人们知道他正在处理Directions
而不是Points
或Normals
。当然,没有什么可以阻止你传递Point
或Normal
,因为它们都是Vectors
(只是别名)。
我想知道是否有一种非开销方式强制程序员(即编译器警告级别4)传递显式声明为Direction
的内容(不会在不同结构中多次复制Vector
结构或继承多次来自Vector
结构)如果没有,程序员需要做一个显式的强制转换(这只是一个noop)? (例如Haskell具有此功能)
struct Vector {
// lots of methods
float x, y, z;
};
typedef Vector Point;
typedef Vector Direction;
typedef Vector Normal;
Normal Normalize(const Direction &) {
...
}
答案 0 :(得分:2)
你也可以使用模板,而不必重新实现所有构造函数:
template<typename tag>
struct Vector {
...
};
namespace tags {
struct point;
struct direction;
struct normal;
}
typedef Vector<tags::point> Point;
typedef Vector<tags::direction> Direction;
typedef Vector<tags::normal> Normal;
Normal Normalize(const Direction &) {
...
}
但是请注意,虽然它没有运行时开销,但是它无法听到代码大小(用每个不同的标签实例化模板),以及编译时间开销(合并来自每个实例的所有弱符号)翻译单元成单个实例)。
你可以通过提供一个非模板化的基类来进行某种程度的缓解,这个基类可以实现&#34;实际工作&#34;。
答案 1 :(得分:1)
唯一的方法是你暗示你不喜欢,但这里是:
struct Point : Vector {};
struct Direction : Vector {};
struct Normal : Vector{};
除了需要定义和委派您可能拥有的任何构造函数之外,没有多少缺点。
对于C和具体使用GCC,这里是关于此主题的上一个问题:Warn if another typedef'd name of a type is used in an argument list
答案 2 :(得分:1)
当然你可以做到。你可以使用继承。只要您不使用虚拟方法,就不会产生运行时开销。
代码如下所示:
struct Vector3d {
float x, y, z;
};
struct Direction :
public Vector3d {
};
如果您有想要使用的特殊构造,可以使用声明将它们包含在子节点中。