1

Im trying to add setter and getter functions to my classes.

In my mind it makes my classes look neater doing it like this.

I wanted to know what way is better, using a macro or using a template, what is faster?

#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()
{
}
vusuzireru
  • 53
  • 5
  • 3
    They should both be equally fast. But you might as well just make it `public: float myFloat;` and skip all the boilerplate, because it's not really adding anything here. Also, you shouldn't do `_MacroFloat`. [That's a reserved identifier](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – Cornstalks May 18 '17 at 03:08
  • The macro provides a variable, a getter, and a setter. The template provides just a variable. How can you compare the two? – R Sahu May 18 '17 at 03:09
  • 1
    @RSahu: It's pretty easy to compare the two... the OP gives usage examples of each one in the constructor for that very purpose. – Cornstalks May 18 '17 at 03:11
  • if the property cannot be default constructed then the Macro version would probably becomes more unreadable. anyway, I agree with Cornstalks that you should not use these at all. – apple apple May 18 '17 at 04:07

2 Answers2

2

From the point of view a client function,

Property<float> TemplateFloat;

is no better then

float myFloat;

You are exposing a member variable and letting the user work with a member variable directly.

The macro provides not only a private member variable but also a public getter function and a public setter function.

Based on that, I think the macro method is better.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

As written, this is public data. The methods you use will be optimized away in your binary, so it won't even give you ABI stability between versions.

The dress you put it in (a template or a macro) is just lipstick on a pig.

If you want zero-cost abstraction around a member variable, then there is also zero benefit.

If you want a layer of indirection that gives you ABI stability, none of these do it.

If you want the ability to change the implementation of these templates/macros for special cases, then what you want to change it to needs to be factored in. Even if only a set of samples of what you might want to do.


As a general rule, if you have a solution that involves using macros and another that doesn't, don't use macros. Macros do not respect scope or namespaces, most compilers are horrible at debugging through them, and while template errors are extremely long macros have the same kind of errors but don't provide you with the diagnostics to help you find out the problem.

As an aside, in both cases, you are lacking proper consideration for rvalue semantics.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524