Thread: accessing private class data low overhead

  1. #16
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Also, I'm not sure how many compilers are able to deduce that the reference always points to the member, so this could actually earn you a greater speed penalty (an indirection) than an accessor function (nothing, if inlined).
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #17
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Should do it if there's only one constructor.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #18
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You would have to make the constructor body visible to all clients of the class, then. Defeats the point, doesn't it?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #19
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Making the variable available publicly is a bad idea but not a terrible one if you are the only one who is ever going to see the code such as for a home project. Keep in mind you would never do this in a professional project which I would argue means you probably should not do it in a home project.

    However it is also possible that the compiler will auto-inline your accessors and mutators if it can. By stating a function is inline you are telling the compiler you would like for it to be such but the compiler does not have to make it inline.

    Because of this and because you must expose code for inline I have moved away from using it. I will say though that there are some private variables that only the class needs to know about and these do not need to be exposed. I've seen classes where the designer felt the need to expose every single private and protected variable via setters and getters. It was just as hard to maintain that class as it would have been had they been made public. The only thing the class really did was force the user of the class to go through a function to get/set a variable and force the compiler, if it could not inline, to setup a stack frame for the call.

    I too detest a lot of the function calls to get/set variables. For instance in my 3D projects I use Direct3D. Nearly every single class needs some access to the doggone device pointer. All the code ends up looking like:

    Code:
    SomeApp::GetInstance()->GetDevice()->blah blah blah
    I have found that if a function needs this pointer a lot then I save it off locally with one GetDevice() and then use it in all the calls after it that need it. Does it make any difference performance wise? Probably not since the compiler probably inlines the getter anyways. But it sure makes the line of code shorter.

    I could expose the device via extern but then that means anyone can Release() it. However my getter has the same problem. It does not protect the pointer at all so someone could call Release() on it as well. Protecting the pointer, however, could cause other issues since it is a pointer to a COM interface and cannot be deleted as a normal pointer - aka no boost. I could write a templated COM ref counted pointer class for sure or I could only allow access to the device by the graphics system. If anyone writing a class for the graphics system attempts to release the device after getting it they probably should not be working on a class for graphics in the first place. In this instance I would say the templated approach is overkill since it is just as easy to make a hard fast rule that if you get the device you should never ever call Release() on it. This is easy enough to enforce but then the template isn't all that hard to write either and doesn't obfuscate the code all that much. If the user of the class doesn't understand template syntax then they, too, should probably not be writing classes for the system.

    EDIT:
    After some thought I could use boost on the device pointer but that would require wrapping the device in a class and in the destructor I would release the device.
    Last edited by VirtualAce; 07-25-2009 at 12:07 PM.

  5. #20
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by CornedBee View Post
    You would have to make the constructor body visible to all clients of the class, then. Defeats the point, doesn't it?
    Busted!
    Yup. I could say the implementation for the setter is still opaque, but the data member and the getter definitely are not.

    Anyways, I don't intend to follow that code anywhere. Simply because of the following...

    Quote Originally Posted by Bubba View Post
    I too detest a lot of the function calls to get/set variables. For instance in my 3D projects I use Direct3D. Nearly every single class needs some access to the doggone device pointer. All the code ends up looking like:

    Code:
    SomeApp::GetInstance()->GetDevice()->blah blah blah
    It's funny, isn't it? I mean, I agree entirely with you. I feel exactly the same. But if we look at it from a functional point of view, we should be glad, not annoyed. That's a perfectly healthy, objective and intuitive method for member access. However there's something in this that irks most of us, for some reason.

    My classes rarely feature get/set prefixes. I find these to be my main source of unjustified annoyance. Naturally, everything that should stay private, stays private. No question about that. But those that do need to be exposed through member access operations are simply named after the data member itself. And for that I follow a simple naming convention for all my private members (functions included). I postfix a underscore.

    Code:
    class CUser {
    
    public:
    
        /*... */
    
        std::string Name() { return name_; }
        char Age() { return age_; }
        
        void Name(std::string str) { name_ = str; }
        void Age(char val) { age_ = val; }
    
    private:
    
        std::string name_;
        char        age_;
    
    };
    So, while I still promote the use of setters/getters I stay away from prefixing these operations. Meanwhile, every time anyone sees a symbol on any of my libraries with a postfixed underscore they know it's a private member, regadless. I do use the is and exists prefix when necessary, but that's about it .

    As for function inlining, I do not bother with it for the same reasons brewbuck exposed and you address too. But, going back to the OP initial post I honestly don't worry much about member access performance. If there was a really good reason for that, I'd probably just copy the member to the stack before whatever performance critical event took its place and that would beat anything we could come up in terms of class optimization.
    Last edited by Mario F.; 07-25-2009 at 12:44 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #21
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Your lack of get and set in the function name is similar to the property concept in C# and, I think, Java. I'm not a Java fella so I don't know much about it.

    Properties feel 'ok' in C# but under the hood it's the same get/set idea. Maybe I feel better about them in C# b/c they are part of the language as opposed to being a construct I created with the language.

    I guess no one ever said that C++ was going to show you the correct way to do things and would not stop you from doing it the wrong way. If it did none of us would love it as much as we do.

    But the fact that I have to go through a hideous function call to get a variable I just got access to a couple of milliseconds ago just irritates me. Another thing that irritates me is I have no idea if said compiler inlined my call to eliminate the function call overhead. I don't think I will ever get 'over' those two annoyances while programming in C++. So every time I make a getter that just returns a value via a function call and a setter that sets a value via a function call I throw up a bit in the back of my throat.
    Last edited by VirtualAce; 07-25-2009 at 02:24 PM.

  7. #22
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    If you need super-fast access to a bunch of state, then what you're talking about isn't really an object anymore but an algorithm which operates on a given data structure. One of the traps that OOP users can fall into is thinking of everything in terms of objects which encapsulate state. In some cases the state itself is what is of interest, and the method by which this data is manipulated is only ancillary.

    You can still have objects, but these objects are now operators on the state instead of containers for it. The state container becomes something extremely simple, like a vector.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #23
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Wasn't there a properties proposal sometime during C++0x life? I could swear I saw that once.

    My first contact with properties was with Visual Basic, introduced in 4.0 if I'm not mistaken. I did appreciate the syntactic simplicity of class usage in VB exactly because of that. It's funny because one of the first things I tried when I started learning C++ was exactly to match that simplicity.

    I agree it can be an annoyance in C++ over the extra typing. But I don't share the disgust
    The function notation makes today a lot more sense to me than properties.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #24
    Registered User
    Join Date
    Jul 2009
    Posts
    24
    Quote Originally Posted by brewbuck View Post
    If you need super-fast access to a bunch of state, then what you're talking about isn't really an object anymore but an algorithm which operates on a given data structure. One of the traps that OOP users can fall into is thinking of everything in terms of objects which encapsulate state. In some cases the state itself is what is of interest, and the method by which this data is manipulated is only ancillary.

    You can still have objects, but these objects are now operators on the state instead of containers for it. The state container becomes something extremely simple, like a vector.
    brewbuck can you expand further? this is closer to what I am looking to do and your comments seem insightful

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Accessing private Data members
    By Emeighty in forum C++ Programming
    Replies: 17
    Last Post: 08-14-2008, 11:16 PM
  3. Can't Access the private member from base class
    By planet_abhi in forum C# Programming
    Replies: 3
    Last Post: 01-09-2006, 04:30 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. can't insert data into my B-Tree class structure
    By daluu in forum C++ Programming
    Replies: 0
    Last Post: 12-05-2002, 06:03 PM

Tags for this Thread