c ++类属性setter getter宏vs模板

时间:2017-05-18 02:57:50

标签: c++ c++11

我试图将setter和getter函数添加到我的类中。

在我看来,它让我的课看起来更整洁。

我想知道哪种方式更好,使用宏或使用模板,什么更快?

#define PropertyM(type, var) \
private: \
    type _##var; \
public: \
    type Get##var() { return _##var; }\
    void Set##var(type val) { _##var = val; }


template<typename T>
class Property
{
protected:
    T m_val;

public:
    inline Property() {}
    inline Property(T val) { m_val = val; }

    inline void Set(const T &a) { m_val = a; }
    inline T Get() { return m_val; }

    operator T() { return m_val; }
    T &operator=(const T &a) { return m_val = a; }
};


class Test
{
public:
    Test();
    ~Test();

    Property<float> TemplateFloat;
    PropertyM(float, MacroFloat)
};

Test::Test() : TemplateFloat(0.f), _MacroFloat(0.f)
{
    // Just a example
    if (TemplateFloat != 1.f)
        TemplateFloat = 1.f;

    if (TemplateFloat.Get() != 2.f)
        TemplateFloat.Set(2.f);

    if (GetMacroFloat() != 1.f)
        SetMacroFloat(1.f);
}

Test::~Test()
{
}

2 个答案:

答案 0 :(得分:2)

从客户端功能的角度来看,

Property<float> TemplateFloat;

并不比

更好
float myFloat;

您正在公开成员变量并让用户直接使用成员变量。

宏不仅提供private成员变量,还提供public getter函数和public setter函数。

基于此,我认为宏观方法更好。

答案 1 :(得分:0)

如上所述,这是公共数据。您使用的方法将在二进制文件中进行优化,因此它甚至不会在版本之间为您提供ABI稳定性。

你穿上的衣服(模板或宏)只是猪的口红。

如果你想在成员变量周围进行零成本抽象,那么也没有任何好处。

如果你想要一个为你提供ABI稳定性的间接层,那么这些都不会这样做。

如果您希望能够针对特殊情况更改这些模板/宏的实现,那么您需要将其更改为需要考虑的因素。即使只是一组您可能想要做的样本。

作为一般规则,如果您有一个涉及使用宏的解决方案而另一个不使用宏的解决方案,请不要使用宏。宏不尊重范围或命名空间,大多数编译器在通过它们进行调试时非常糟糕,虽然模板错误非常长,但宏会出现同样的错误,但是没有为您提供诊断来帮助您找出问题所在。

顺便说一下,在这两种情况下,你都缺乏对rvalue语义的正确考虑。