Search code examples
c++cgetter-setter

Getter & Setter in C++/C project?


I am trying to update C/C++ code, want to use getters and setters for tracking and/or testing.

Made a template class for general declarations

#include <iostream>

using namespace std;

#define TRACK_PROP(a,b) TrackProp<a> b(#b);
#define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c);

template <class T>
class TrackProp {
public:
    T _content;
    const char* Name;

    TrackProp(const char* name) { Name = name; }
    TrackProp(const char* name, T val) { Name = name; _content = val; }
    T operator =(T right)
    {
        if (_content != right) {
            cout << Name << ":" << _content << "->" << right << endl;
            _content = right;
        }
        return _content;
    }

    operator T() const
    {
        return _content;
    }

    T operator ++()
    {
        operator = (_content + 1);
        return _content;
    }
    T operator ++(int)
    {
        operator = (_content + 1);
        return _content - 1;
    }
    T operator --()
    {
        operator = (_content - 1);
        return _content;
    }
    T operator --(int)
    {
        operator = (_content - 1);
        return _content + 1;
    }
    T operator +=(int right)
    {
        operator = (_content + right);
        return _content;
    }
    T operator -=(int right)
    {
        operator = (_content - right);
        return _content;
    }
};

I can easily translate declarations now

int foo;
int bar = 2;

// These 2 or even some object can be declared by
TRACK_PROP(int, foo);
TRACK_PROP_SET(int, bar, 2);
foo = 1; // = operator /setter
int baz;
baz = bar; // () operator /getter

But having problems when they are used in C files too.

How would you change it to keep Get/Set/Name functionality and be able to use it also in C files as simply as in C++ ?


Solution

  • I am a not expert, but isn't it too complicated to generate C++/C functions and replace your variable by some macro ? Your a bit modified version:

    #ifdef __cplusplus
    #define TRACK_C(a, b) \
    extern "C" a _get$##b() { \
    return b; \
    }; \
    extern "C" void _set$##b(a c) { \
    ##b = c; \
    };
    #define TRACK_PROP(a,b) TrackProp<a> b(#b); \
    TRACK_C(a, b)
    #define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c); \
    TRACK_C(a, b)
    template <class T>
    class TrackProp {
    public:
        T _content;
        const char* Name;
    
        TrackProp(const char* name) { Name = name; }
        TrackProp(const char* name, T val) { Name = name; _content = val; }
        T operator =(T right)
        {
            if (_content != right) {
                cout << Name << ":" << _content << "->" << right << endl;
                _content = right;
            }
            return _content;
        }
    
        operator T() const
        {
            return _content;
        }
    };
    #else
    #define TRACK_C(a,b) \
    a _get$##b(); \
    void _set$##b(a);
    #define TRACK_GET(b) _get$##b()
    #define TRACK_SET(b,c) _set$##b(c)
    #endif
    

    In C++ you can still use you operators

    #include <iostream>
    #include "TRACK_PROP.h"
    
    using namespace std;
    
    TRACK_PROP(int, demo);
    
    extern "C" void test();
    
    void main(void) {
        demo = 123;
        cout << demo;
        test();
    }
    

    And in C replace a demo variable use by my macros:

    #include "TRACK_PROP.h"
    
    TRACK_C(int, demo)
    
    void test() {
        // demo = 1
        TRACK_SET(demo, 1);
        // demo = 3*demo;
        TRACK_SET(demo, 3*TRACK_GET(demo)));
    }
    

    It would be great if there will be easier option, but I do not know about any direct way too...