Thread: Opinions on my get/set approach

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    63

    Opinions on my get/set approach

    I did a forum and google search on c++ getters and setters and found way too many hits and many diverse opinions.
    I would ask your opinion on the approach I present here.
    Early in my c++ studies I found I missed the built in getters and setters from my early VB days and more recently from PowerBASIC COM classes. I found a c++ template which I have used but it was lacking in it's implementation.
    Recently I ran across another approach which I suplimented with the macros: PropGet,PropSet and PropGetSet.
    Early on in my c++ education I adopted the method of prefixing all my private/protected variables with "m_"
    This provides me with setters/getters with a minimum amount of coding.


    Thank you,
    James


    Code:
    #include <iostream>
    #include <string>
    typedef signed char SCHAR;
    using namespace std;
    //==============================================================================
    #define PropGet(p,t) t p(){return m_##p;}
    #define PropSet(p,t) void p(t p){m_##p=p;}
    #define PropGetSet(p,t) PropGet(p,t)PropSet(p,t)
    //==============================================================================
    
    
    class PropTestOne
    {
    protected:
        int      m_Count;
        long     m_v1;
        float    m_f1;
        string   m_S1;
        SCHAR    m_c1;
    public:
        PropGetSet(Count, int);
        PropGetSet(v1, long);
        PropGetSet(f1, float);
        PropGetSet(S1, string);
        PropGetSet(c1, SCHAR);
    };
    
    
    class PropTestTwo
    {
    protected:
        string  m_first;
        string  m_mid;
        string  m_last;
        string  m_full;
    public:
        PropGetSet(first, string);
        PropGetSet(mid, string);
        PropGetSet(last, string);
        PropGetSet(full, string);
    };
    
    
    int f1 (int n1, int n2)
    {
        return n1 + n2;
    }
    
    
    int main ()
    {
        PropTestOne  test1;
        PropTestTwo  test2;
        int      i = {0};
        int      j = {0};
        float    f = {0.0};
        SCHAR    c = {0};
        string  xs;
        //assign the value 5 to i
        i = 5;
        //assign test1 Count variable the value of i
        test1.Count(i);
        //Print the contents of test1's Count Variable
        cout << test1.Count() << endl;
        //assign the value 8 to i
        i = 8;
        //assign test1 Count variable the value of i again
        test1.Count(i);
        //assign j the value of it's Count Variable
        j = test1.Count();
        //did it work?
        cout << "j = " << j << endl;
        //Continue......
        test1.Count(327);
        cout << "test1.Count = " << test1.Count() << endl;
        //use v1
        test1.v1(134567);
        j = test1.v1();
        cout << " j = " << j << endl;
        //assign one test1 var to another
        test1.v1(test1.Count());
        cout << "test1.v1 = " << test1.v1() << endl;
        //do a bit of addition
        j = test1.v1() + test1.Count();
        cout << "j = " << j << endl;
        //how about floats?
        test1.f1(134.567);
        f = test1.f1();
        cout << "f = " << f << endl;
        f = test1.f1() + 100.789321;
        cout << "f = " << f << endl;
        //will it work with	a c++ std library string
        test1.S1("James");
        xs = test1.S1();
        cout << " xs = " << xs << endl;
        test1.c1(-88);
        c = test1.c1();
        cout << "c = " << (float)c << endl;
        //Print "c = ";c
        test2.first("James");
        test2.mid("C.");
        test2.last("Fuller");
        xs = test2.first() + " " + test2.mid() + " " + test2.last();
        test2.full(xs);
        cout << "xs = " << xs << endl;
        j = f1( test1.v1(), test1.Count());
        cout << "pass props to function" << endl;
        cout << "j = " << j << endl;
    }

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I'd recommend getting rid of those macros, all they seem to do is obfuscate your code, plus they don't seem correct:

    main.cpp||In member function ‘void PropTestOne::Count(int)’:|
    main.cpp|7|warning: declaration of ‘Count’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|21|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestOne::v1(long int)’:|
    main.cpp|7|warning: declaration of ‘v1’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|22|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestOne::f1(float)’:|
    main.cpp|7|warning: declaration of ‘f1’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|23|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestOne::S1(std::string)’:|
    main.cpp|7|warning: declaration of ‘S1’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|24|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestOne::c1(SCHAR)’:|
    main.cpp|7|warning: declaration of ‘c1’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|25|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestTwo::first(std::string)’:|
    main.cpp|7|warning: declaration of ‘first’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|37|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestTwo::mid(std::string)’:|
    main.cpp|7|warning: declaration of ‘mid’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|38|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestTwo::last(std::string)’:|
    main.cpp|7|warning: declaration of ‘last’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|39|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In member function ‘void PropTestTwo::full(std::string)’:|
    main.cpp|7|warning: declaration of ‘full’ shadows a member of 'this' [-Wshadow]|
    main.cpp|8|note: in expansion of macro ‘PropSet’|
    main.cpp|40|note: in expansion of macro ‘PropGetSet’|
    main.cpp||In constructor ‘PropTestOne::PropTestOne()’:|
    main.cpp|12|warning: ‘PropTestOne::m_Count’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|12|warning: ‘PropTestOne::m_v1’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|12|warning: ‘PropTestOne::m_f1’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|12|warning: ‘PropTestOne::m_S1’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|12|warning: ‘PropTestOne::m_c1’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp||In function ‘int main()’:|
    main.cpp|52|note: synthesized method ‘PropTestOne::PropTestOne()’ first required here |
    main.cpp||In constructor ‘PropTestTwo::PropTestTwo()’:|
    main.cpp|29|warning: ‘PropTestTwo::m_first’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|29|warning: ‘PropTestTwo::m_mid’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|29|warning: ‘PropTestTwo::m_last’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp|29|warning: ‘PropTestTwo::m_full’ should be initialized in the member initialization list [-Weffc++]|
    main.cpp||In function ‘int main()’:|
    main.cpp|53|note: synthesized method ‘PropTestTwo::PropTestTwo()’ first required here |
    ||=== Build finished: 0 errors, 18 warnings (0 minutes, 3 seconds) ===|
    Jim

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by jcfuller View Post
    Code:
    #define PropGet(p,t) t p(){return m_##p;}
    #define PropSet(p,t) void p(t p){m_##p=p;}
    should really be:

    Code:
    #define PropGet(p,t) const t& p() const {return m_##p;}
    #define PropSet(p,t) void p(const t& param_##p){m_##p=param_##p;}
    note the const-correctness and the addition of a prefix to differentiate between the function name and its parameter. Note the const reference return value is not required. You can return by value, but the getter function should generally be marked const.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I would do without the macros, myself.

    More significantly, a common point of setters and getters is to permit error checking or enforcement of constraints (for example, prevent setting some member to an invalid value). Your approach does not achieve that. And macros would make it more difficult to prevent invalid combinations (for example, if constraints on one member depend on values of another member). Yes, it is possible, but you would either spend your time maintaining additional macros to give flexibility, or working around the macros you have.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    don't use macro functions at all in C++. use Inline functions instead.

    also , I don't like the use of getters and setters for ALL the member functions , I think it misses the original point of them.
    getters and setters forbid you from touching variables you shouldn't touch . you can get or set variable you suppose to.
    In my opinion , you should create getters and setters only for inner variables/objects that are needed to be handle publicly .

    let's take an example from the real life:
    nobody can pull your lungs or heart whenever they want. Heart is a private object you have , and nobody can see , touch , change or mess with it so easly.
    The blood vessels , on the contrary , can always excess your heart , your heart has only INNER excess.
    you clothes can be seen , switched or be touched , your clothes has PUBLIC excess .

    let's say you need to implement a Person Class - would you implement getter and setter for the Heart object? and would you implement getter and setter for the Clothes object?

  6. #6
    Registered User
    Join Date
    Mar 2013
    Posts
    63
    Thank you all for your insights.
    Would not Elkvis fix-up be similar to the VB and C# Auto-implemented properties?
    If I need to check the var for some constraint in a Set I would use the conventional setVar.

    James

  7. #7
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by Dave11 View Post
    you clothes can be seen , switched or be touched , your clothes has PUBLIC excess .
    Heheh.

    Quote Originally Posted by Dave11 View Post
    let's say you need to implement a Person Class - would you implement getter and setter for the Heart object? and would you implement getter and setter for the Clothes object?
    I know you're expecting "yes" and "no" respectively, but...

    I would probably not have any accessors for the heart, it should be internally managed. I'd guess that your Person is poorly designed if you had to bother with the heart at all from the outside.

    I would indeed use getters/setters for the clothes. getClothes might throw if the person was naked, setClothes might throw if the size of the clothes don't fit the person.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Yarin
    I'd guess that your Person is poorly designed if you had to bother with the heart at all from the outside.
    But... a person might wear his/her heart on his/her sleeve.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    Quote Originally Posted by Yarin View Post
    Heheh.

    I know you're expecting "yes" and "no" respectively, but...

    I would probably not have any accessors for the heart, it should be internally managed. I'd guess that your Person is poorly designed if you had to bother with the heart at all from the outside.

    I would indeed use getters/setters for the clothes. getClothes might throw if the person was naked, setClothes might throw if the size of the clothes don't fit the person.
    actually , this is what I meant. I wouldn't implement a setter&getter for the heart , and even so , they weren't public, because you can't get or set a heart. I would certainly implement a getter and a setter for the clothes. the point is , one should ask himself (in 95% of the time) "In real life, does this object is private or public? can it be set or gotten?"

  10. #10
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    BTW , this is may be whole different point , but Friendship classes comes handy in these rare scenarios.
    this is my main argument when talking to java and C# developers about friend classes and functions.
    when used correctly , friendship can enhance encapsulation and not destroy it.

    Heart is an inner object , a person from the street may not be able to mess with it , but a surgeon doctor , electricity , and heart medications are.
    I want the heart object to be private , yet, some other classes may manipulate it at will.
    I may implement getter and setter for the heart, but that mean that for the sake of few classes I exposed private object to anyone.
    I may want to keep the heart private without any getters and setters , but then a surgeon doctor can't do surgery on it.
    what's the C++ solution for this?
    Friendship!
    the heart is still private for anyone , except rare classes that can really get to it , like surgeon doctor

  11. #11
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by Dave11 View Post
    the heart is still private for anyone , except rare classes that can really get to it , like surgeon doctor
    Friendshipping is the wrong solution to the problem.
    In a perfect world, you won't even need heart surgery, or heart medications, or defibrillation. Likewise, I would argue, that in a proper design, the proverbial heart object will never need to be accessed from outside the body object.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Friendshipping is the wrong solution to the problem.
    O_o

    Out of curiosity, do you and Dave11 really just let anyone change/remove/replace your clothing?

    *shrug*

    I'm pretty sure strangers would not want to remove my clothing; that just seems an odd mode of access.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  13. #13
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Dave11 View Post
    would you implement getter and setter for the Heart object?
    Getter? Yes. Setter? No.

    The getter would return a const reference, which would then expose public functions like GetPulseRate.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  14. #14
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by Elkvis View Post
    The getter would return a const reference, which would then expose public functions like GetPulseRate.
    GetPulseRate should be a Body member (which, internally would access the heart, of course). Think about it, I don't check your pulse by touching your heart, I do it by touching your body.


    Quote Originally Posted by phantomotap View Post
    Out of curiosity, do you and Dave11 really just let anyone change/remove/replace your clothing?
    I call BS, there's no you no way you friend all the classes you expect to be accessing your class.
    Last edited by Yarin; 01-06-2015 at 01:03 PM.

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    The getter would return a const reference, which would then expose public functions like GetPulseRate.
    O_o

    Code:
    const_cast<Heart &>(aPerson.heart()) = Heart(no_pulse);
    Wrapping public methods of component, contained, objects is often enough a good idea.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. I need some opinions about VC++ vs C++
    By Dante Wingates in forum C++ Programming
    Replies: 19
    Last Post: 06-24-2010, 10:05 AM
  2. Opinions?
    By Decrypt in forum C++ Programming
    Replies: 1
    Last Post: 09-18-2005, 05:29 PM
  3. C++ Opinions
    By Cgawd in forum C++ Programming
    Replies: 15
    Last Post: 10-28-2002, 06:01 PM
  4. Need some opinions
    By Fool in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 12-17-2001, 07:39 PM
  5. Opinions
    By Betazep in forum C++ Programming
    Replies: 1
    Last Post: 12-15-2001, 03:34 PM