使用预处理器的良好实践声明多个类似的类?

Nax*_*im' 2 c++ c-preprocessor

假设我想创建一个数学库.我需要处理的载体在不同的维度,所以我想有每个维度中的一个类(又名Vector2,Vector3,Vector4...)

到现在为止还挺好.但它会导致严重的代码重复,因为Vector3主要是某些函数中Vector2使用的z属性.

所以我有个主意.代码复制是机器而不是人类的任务,所以我可以这样写:

在Vector.hpp中:

#ifndef VECTOR_HPP
#define VECTOR_HPP

#define VECTOR_DIM 2
#include "_Vector.hpp"
#define VECTOR_DIM 3
#include "_Vector.hpp"
#define VECTOR_DIM 4
#include "_Vector.hpp"
#undef VECTOR_DIM

#endif
Run Code Online (Sandbox Code Playgroud)

在_Vector.hpp中:

// This header was not protected from multiple inclusions on purpose

#define VECTOR_NAME Vector ## VECTOR_DIM

class VECTOR_NAME
{
public:
    // Some methods here ...

    float x;
    float y;
#if VECTOR_DIM >= 3
    float z;
#endif
#if VECTOR_DIM >= 4
    float w;
#endif
};

#undef VECTOR_NAME
Run Code Online (Sandbox Code Playgroud)

这会简化任务,但这是一种好的做法吗?

R S*_*ahu 7

鉴于您发布的代码,您可以使用以下代码轻松替换它,而不必使用预处理器技巧.

template <int dim> struct Data;

template <> struct Data<2>
{
   float x;
   float y;
};

template <> struct Data<3> : Data<2>
{
   float z;
};

template <> struct Data<4> : Data<3>
{
   float w;
};

template <int dim> class Vector
{
   public:
      // Some methods here ...
      Data<dim> data;
};
Run Code Online (Sandbox Code Playgroud)

您可以轻松扩展VectorData支持更多功能.

不仅如此,您还可以通过确保仅为预先确定的有效值集定义来防止dim实例化时VectorData无效值dim.

  • @Nax,一般来说,使用模板是比使用预处理器宏更好的方法。如果您想得足够仔细,那么您尝试使用预处理器宏所做的事情可能可以使用模板来完成。该站点可能不是弄清楚如何在复杂的代码库中使用模板的最佳场所。您必须以正确的精神接受在本网站上收到的答案和建议,并尽可能将它们应用到您的复杂项目中。 (2认同)