Thread: Top methods for accesing Private data

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    71

    Top methods for accesing Private data

    I have yet seens 3 methods that are considered as good or bad in a different manner, ill mention them here really quick:
    -Get/Set functions in the class public area
    -Friend
    -#define private of class

    I heard the functions are the most common but they save time, also pretty unreadable code etc.

    Thats all i have read and im not expirienced in accesing private data, so im asking you, please post here what method you are using.

    PS: i r newcommer, hi everyone :P

  2. #2
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Typically, you should design your class in such a way that not much private data is needed to be accessed by outsiders.
    If needed often to be seen and modified directly , the data should not be private at all. (For example, components of a 'Point' class).

    Otherwise provide functions for them. (Non member functions are sometimes recommended by experts but I repeatedly fail to understand that logic.)

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    71
    Could be more specific please

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Get/Set functions in the class public area
    I'm sure you'll get some arguments about "getters and setters". If done properly "getters and setters" are usually better than "public:".

    The "getters and setters" approach has a lot of advantages over "public:". I'll stick with these two:

    If using a proper interface, the data type (the real class member variable) can be changed freely without changing the interface.

    If using a proper interface, the methods can be virtual allowing different classes in a hierarchy to store and operate as appropriate to the class implementation.

    Friend
    Saying "friend" is the C++ way of saying "This can't be done without the protected or private interface but only works as, works better as, or has no business being a class method (function).".

    #define private of class
    O_o

    What? I really, really need to know what this means.

    I heard the functions are the most common but they save time, also pretty unreadable code etc.
    o_O

    What!?

    Non member functions are sometimes recommended by experts but I repeatedly fail to understand that logic.
    *shrug*

    It is sometimes necessary for a facility to be implemented as a non-member function. Consider the operator overloads necessary for `std:stream' compatibility or the `std::swap' protocol.

    In practice, everything else can be written as a member function; however, non-member functions increase encapsulation. A lot of new programmers misunderstand the previous sentence. The class itself doesn't have better encapsulation over a member function just because a facility is implemented as a non-member function. That would be silly. The client code is implemented as being better encapsulated because no other options are available.

    For the sake of argument, consider a container class that isn't `std::container<???>' compatible. (Unfortunately, this is a real world issue as a lot of libraries define their own standard.) A template function that operates on containers of `value_type' `int'.

    Code:
    template
    <
        typename FContainer
    >
    void DoSomething
    (
        const FContainer & fData
    )
    {
        // ...
        FContainer::iterator lBegin(fData.Begin());
        FContainer::iterator lEnd(fData.End());
        // ...
    }
    The code underlying the container is, for this purpose, irrelevant. The above code isn't as resilient to change as it might be because it is looking inside the class. Yes, the `Begin' and `End' methods are assumed to be "public:". That only says that the methods are intentionally made usable from the perspective of C++ client code. (C++ doesn't set the standard for good design.) Even though it is in the "public:" interface the exact signature may change. If that interface is used throughout unfamiliar client code the result is brittle client code.

    Code:
    template
    <
        typename FContainer
    >
    void DoSomething
    (
        const FContainer & fData
    )
    {
        // ...
        Iterator<FContainer>::UResult lBegin(Begin(fData));
        Iterator<FContainer>::UResult lEnd(End(fData));
        // ...
    }
    This alternative code isolates changes in a class, "public:" or not, to a few lines unrelated to the implementation of this relevant client code.

    Soma
    Last edited by phantomotap; 05-06-2012 at 12:21 AM.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Essentially, manasij is saying that you're asking the wrong question. It is irrelevant how private members are accessed since, by definition, access to them should only occur via the class interface.

    From a design perspective, the interface supplied to the outside world by the class consists of both its public members (which includes both public data and public member functions) and its friends. The interface supplied to derived classes consists of public and protected members, as well as friends.

    Your "third" method (#define private) is NOT a common method since, according to the standard redefining any language keyword yields undefined behaviour. It is sometimes used by hackers to circumvent member access attributes, but is not guaranteed to work as intended. Even if it yields the desired behaviour with one compiler, it is not guaranteed to do so when the code is rebuilt using another compiler.

    Manasij's comment about non-member functions is referring to the fact that non-member functions can operate on the class just as member functions can but non-member functions are less tightly coupled to the class definition than are member functions. From a design and maintenance perspective, lower coupling is generally advantageous.
    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.

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Your "third" method (#define private) is NOT a common method since, according to the standard redefining any language keyword yields undefined behaviour.
    O_o

    Oh. Is that what he meant?

    Wow. That's way less stupid than what I was thinking. Still wrong; just not nearly as stupid.

    Soma

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by phantomotap View Post
    Oh. Is that what he meant?
    That is my interpretation. I've seen a few fools advocating the technique in my time (usually trying to access private members, when there is no public accessor).

    Quote Originally Posted by phantomotap View Post
    Wow. That's way less stupid than what I was thinking. Still wrong; just not nearly as stupid.
    Personally, I would describe a technique that involves deliberate reliance on undefined behaviour to compensate for sloppy design, or to gain access to private data that (by definition) should not be accessed outside the class interface, is the height of stupidity.
    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.

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Personally, I would describe a technique that involves deliberate reliance on undefined behaviour to get around sloppy design is the height of stupidity.
    ^_^;

    Fair enough...

    Soma

  9. #9
    Registered User
    Join Date
    May 2012
    Posts
    71
    I have read an article but ill stop myself from adversting
    Getters and Setters are Evil
    Use of getters and setters is in opposition to the fundamentals of object oriented design: Data abstraction and encapsulation. Overuse of getters and setters will make your code less agile and maintainable in the long run. They ultimately expose the underlying implementation of your class, locking implementation details into the interface of the class.Imagine your 'std::string Foo::bar' field needs to change from a std::string to another string class, that, say, is better optimized or supports a different character-set. You'll need to change the private data field, the getter, the setter, and all the client code of this class that calls these getters and setters.Rather than design your classes to "provide data" and "receive data", design them to "perform operations" or "providide services". Ask yourself why you're writing a "GetBar" function. What are you doing with that data? Perhaps you're displaying that data on or doing some processing on it. Is this process better exposed as a method of Foo?This not to say that getters and setters don't have their purpose. In C# I believe the fundamental reason for their use is to interface with the Visual Studio GUI-design IDE, but if you find yourself writing them in C++, it's probably best to take a step back, look at your design, and see if something is missing.
    Code:
    // A class that represents a user's bank account
    classAccount{ private: int balance_;// in cents, lets say public: constint&GetBalance(){return balance_;} voidSetBalance(int b){ balance_ = b;} }; classDeposit{ private: int ammount_; public: constint&GetAmount(){return ammount_;} voidSetAmmount(int a){ _balance = a;} }; voidDoStuffWithAccount(){ Account a; // print account balance int balance = a.GetBalance(); std::cout << balance; // deposit some money into account Deposit d(10000); a.SetBalance( a.GetBalance()+ d.GetValue());
    }
    t doesn't take very long to see that this is very poorly designed.

    1. Integers are an awful currency datatype
    2. A Deposit should be a function of the Account

    The getters and setters make it more difficult to fix the problems, since the client code DoStuffWithAccount is now bound to the data-type we used to implement the account balance.So, lets make a pass on this code and see what we can improve
    Code:
    // A class that represents a user's bank account
    classAccount{ private: float balance_; public: voidDeposit(float b){ balance_ += b;} voidWithdraw(float w){ balance_ -= w;} voidDisplayDeposit(std::ostream &o){ o << balance_;} }; voidDoStuffWithAccount(){ Account a; // print account balance a.DisplayBalance(std::cout); // deposit some money into account float depositAmt =1000.00; a.Deposit(depositAmt); a.DisplayBalance(std::cout);
    }
    The 'float' is a step in the right direction. Granted, you could have changed the internal type to 'float' and still supported the getter/setter idiom:
    Code:
    classAccount{
    private: // int balance_; // old implementation float balance_; public: // support the old interface constint&GetBalance(){return(int) balance_;} voidSetBalance(int b){ balance_ = b;} // provide a new interface for the float type constfloat&GetBalance(){return balance_;}// not legal! how to expose getter for float as well as int?? voidSetBalance(float b){ balance_ = b;}
    };
    but it doesn't take long to realize that the getter/setter arrangement is doubling your workload and complicating matters as you need to support both the code that used ints and the new code that will use floats. The Deposit function makes it a bit easier to expand the range of types for depositing.An Account-like class is probably not the best example, since "getting" the account balance is a natural operation for an Account. The overall point, though, is that you must be careful with getters and setters. Do not get into the habit of writing getters and setters for every data-member. It is quite easy to expose and lock yourself into an implementation if you are not careful.
    Sorry for the wall of text, im a newcommer and dont wanna risk any warns or worse by adversting other programming webs

    Anyway, what methods do you recomend me to use for accesing private data? What methods do you use in a large projects?
    Last edited by CoffeCat; 05-06-2012 at 01:34 AM.

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Sorry for the wall of text, im a newcommer and dont wanna risk any warns or worse by adversting other programming webs
    So you plagiarized an article instead?

    No! ........ You! That is not okay.

    Post the source of such a quote or don't post at all.

    This. Exactly this! This is why I'm never allowed to be a moderator for more than five minutes.

    [Edit]
    Anyway, what methods do you recomend me to use for accesing private data?
    As manasij7479 and grumpy have discussed: if you need access to "private" data your options are methods (class functions) or friends. There is simply not a third option. (I don't consider the abomination I thought of or the thing grumpy considers an abomination as real options.)
    [/Edit]

    [Edit]
    As a matter of interest, the article rationale is technically flawed in a few ways.

    That doesn't make the general advice ("The overall point, though, is that you must be careful with getters and setters. Do not get into the habit of writing getters and setters for every data-member.") wrong. However, the arguments aren't as good as implied.
    [/Edit]

    [Edit]
    Also as a matter of interest, the article accidentally makes a great case for client code using functions (freestanding non-member functions) instead of methods.

    Client code written against a user defined function provides isolation (lower coupling as grumpy said) from the exact type of changes the article exaggerates.
    [/Edit]

    Soma
    Last edited by phantomotap; 05-06-2012 at 01:53 AM.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Phantomotap, by #define private he must mean The Pickpocket as per GotW #76: Uses and Abuses of Access Rights

    CoffeCat, read the above link. It should answer your questions.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Yeah; grumpy had already suggested that was probably the case.

    Soma

  13. #13
    Registered User
    Join Date
    May 2012
    Posts
    71
    Interesting article iMalc, thank you. Seems the good way is to use some Getters and Setters for variables thatn might actualy change, what this can mean?

  14. #14

  15. #15
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    That "wall of text" completely misses a primary purpose of getters and setters: protection of the user of the class from changes in how the class represents data internally, and vice versa. Specifically, The "wall of text" assumes that, if we change the internal representation of data used by the class, that we must change the signature (eg return type and argument type) of the setters and getters. That is a completely incorrect employment of getters and setters.

    This, for example, is a perfectly valid usage of getters and setters.
    Code:
    class US_Money
    {
         public:
             // constructors
    
             int GetCents() const;
             int GetDollars() const;
    
             void SetCents(int cents);
             void SetDollars(int dollars);
    
         private:
    
             SomeInternalRepresentation  dollars_and_cents;
    };
    
    int US_Money::GetCents() const
    {
         // extract the cents from dollars_and_cents
         return cents;
    }
    
    int US_Money::GetDollars() const
    {
         // extract the dollars from dollars_and_cents
         return dollars;
    }
    
    void US_Money::SetCents(int cents)
    {
          //  insert cents into dollars_and_cents
    }
    
    void US_Money::SetDollars(int dollars)
    {
          //  insert dollars into dollars_and_cents
    }
    Now, in the above, SomeInternalRepresentation can be any type we wish. It can be a floating point value. It can be a structure containing two ints. It can be a single integer representing the total number of cents in a monetary value. It can be a string with values stored in the form "$$$$$$.cc" where the $ and c characters represent integer values.

    The only things that need to be changed if we change SomeInternalRepresentation are the setters and getters. As far as the user of the class is concerned, it behaves the same way, even if we have changed SomeInternalRepresentation. This means that, if we pick (say) float for our internal representation and then, later, decide that we want to use some structure type, that we can. There is no need to change the function that uses the class at all.

    Even better, the getters and setters can do error checking. For example, if the caller does
    Code:
        some_US_money_value.SetCents(102);    //   there are only 100 cents in a dollar
    the setter can take appropriate actions. What actions are deemed appropriate? That is a decision for the class designer. Possibilities might include (1) ignoring a value that is negative or exceeds 99 (2) extracting $1 and 2c components from 102, and adding both. (3) throwing an exception to report an invalid number of cents. The list of possibilities goes on.
    Last edited by grumpy; 05-07-2012 at 05:24 AM.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Composition,private Class member variables and methods
    By sigur47 in forum C++ Programming
    Replies: 13
    Last Post: 01-29-2012, 08:10 PM
  2. Accesing pointer to struct data
    By mosu' in forum C++ Programming
    Replies: 7
    Last Post: 07-18-2006, 10:01 AM
  3. Accesing data from App in Doc
    By drb2k2 in forum Windows Programming
    Replies: 2
    Last Post: 04-16-2003, 03:03 PM
  4. Accesing private data from method of another object
    By QuickSilver in forum C++ Programming
    Replies: 9
    Last Post: 01-16-2002, 04:15 AM