Thread: read-only data members. A question of good practices

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    read-only data members. A question of good practices

    Code:
    class myClass {
    public:
        myClass(): val(0), value(val) {}
        myClass(int x): val(x), value(val) {}
        void set_value(int x) { val = x; }
    private:
        int val;
    public:
        const int &value;
    };
    The above is a minimalist example to illustrate my question...

    Instead of coding getters for every data member, is the const reference considered a correct approach within the context of good programming practices under C++?

    EDIT: I understand this forces me to overload the assignment operator. But still... is this a common practice?
    Last edited by Mario F.; 06-18-2006 at 06:34 AM.
    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.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    Quote Originally Posted by Mario F.
    But still... is this a common practice?
    No. I have never seen references used for that purpose.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    What would be the point of making val private, if you can access it through a reference? Wouldn't it be the same as making val public in the first place?

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No, it would not, because the user can't change val through the reference.

    I've never seen it done, but I see no particular reason why you shouldn't do it, aside from the need for an assignment operator you mentioned, an additional pointer per instance (the reference must actually be stored), and the fact that it would probably confuse most programmers who initially come across it.
    Come to think of it, the space issue is probably the reason why nobody does it. Imagine: on my AMD64, the reference makes each instance of the class go from 4 bytes to 12. That's quite a price to pay.
    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

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you use that method, you cannot change the implementation to anything other than an int value. So if in the future you need to compute the value on the fly instead of saving it in the class instance, then you must change the interface to use a get method instead of the reference and update all that code that uses the class. That is a big reason why you use the get method in the first place.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I've never seen this approach before either, although I guess it's one way of skinning the cat. Personally, I consider there are too many circumstances where I'd want to evolve from something like this to using a getter, and this approach makes more work retrofitting that, so I'd probably just go for the getter upfront.

    Another issue with the approach (other than the space issue and supplying an assignment operator) is that it is also necessary to supply a copy constructor.

    One other alternative to this, with it's own share of trade-offs, is supplying an operator int() for the class.

  7. #7
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by grumpy
    One other alternative to this, with it's own share of trade-offs, is supplying an operator int() for the class.
    Sorry grumpy, but that's a disaster waiting to happen. First you lose all the information in the code that tells you when you're accessing int. Second your class becomes convertible to int and consequently bool.
    so if anyone has this
    Code:
    class anotherClass
    {
    public:
        anotherClass(int);
    };
    myClass instantly becomes convertable to anotherClass, almost certainly not what you want.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ok folks. Thanks for the information.

    It seemed a good option when I first started thinking how could I get read-only data members that map to private members. It would alleviate me of the () operator and it seemed faster than incurring on a getter function call.

    My Visual Basic legacy makes it very intuitive to access a data member directly obj.member, instead of obj.getter(). Private data members can be accessed directly for read-only purposes. It is just an habit I have to lose.

    Thanks again.
    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. #9
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by Mario F.
    Ok folks. Thanks for the information.

    It seemed a good option when I first started thinking how could I get read-only data members that map to private members. It would alleviate me of the () operator and it seemed faster than incurring on a getter function call.

    My Visual Basic legacy makes it very intuitive to access a data member directly obj.member, instead of obj.getter(). Private data members can be accessed directly for read-only purposes. It is just an habit I have to lose.

    Thanks again.
    if you inline the getter function call, the speed penalty disappears.

    Python and C# allow the concepts of Properties, which basically maps a public "variable" to a set/get pair, i.e
    Code:
    // C#
    class aClass
    {
    
       public string Name 
       {
          get 
          {
             Console.WriteLine("called get");
             return name; 
          }
          set 
          {
             Console.WriteLine("called get");
             name = value; // value is a special varialbe
          }
       }
    }
    I think this was in vb as well? Anyway it's quite a nice bit of syntactic sugar, and maintains encapsulation
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Yes, that's the VB paradigm too. Get and Set are full blown code structures by their own right and can be selectively omitted in order to provide concepts like read-only data members and private data members. The syntax also allows for direct access.

    if you inline the getter function call, the speed penalty disappears.
    Yes. No doubt.
    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.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I don't know, for toy programs (which is the kind of program I think we're talking about) the const reference doesn't seem so bad. And when you have data members on the heap it's not trouble to code a copy constructor or an assignment operator, because in that case you need those things anyway. That's when I use it, but then I don't work for anyone.

    In C++ applications used by consumers I doubt that get/set functions are used a lot. When they are there is a good reason for it. There are plenty of better ways to make an interface.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by ChaosEngine
    Sorry grumpy, but that's a disaster waiting to happen. First you lose all the information in the code that tells you when you're accessing int. Second your class becomes convertible to int and consequently bool.
    I don't necessarily agree that's a disaster waiting to happen (almost everything in C++, or any other programming language can be used well or misused), but the sort of concerns you raise are why I described using an operator int() as having it's share of trade-offs.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bytes lost with partial read in UDP
    By mynickmynick in forum Networking/Device Communication
    Replies: 3
    Last Post: 03-31-2009, 02:06 AM
  2. pthread question how would I init this data structure?
    By mr_coffee in forum C Programming
    Replies: 2
    Last Post: 02-23-2009, 12:42 PM
  3. I need help as soon as possible.
    By hyrule in forum C++ Programming
    Replies: 7
    Last Post: 11-09-2005, 05:49 PM
  4. Client-Server Data Read Problem
    By bob2509 in forum C Programming
    Replies: 8
    Last Post: 11-06-2002, 11:47 AM
  5. Read data from file !!!
    By frankiepoon in forum C Programming
    Replies: 2
    Last Post: 10-14-2002, 11:45 PM