Why not allways use a const reference?

Started by
24 comments, last by _the_phantom_ 19 years, 4 months ago
Quote:Original post by Drew_Benton
Quote:Original post by _the_phantom_
... quote ...


Now I know what you are saying, and I have a heck of a lot of books on proper C++ coding stuff (I'm a C++ freak [wink]), but this is all what I have to say. From experience - and I'm talking about a lot of game designing (no games made tohugh [lol])(and I know this is a general forums - thats why our ideas aren't on the same track), the "theorey" of good programming is there to try and help to make some sense of the vastness of C++, but it is just theory - it all changes in practice. Every project is different on its own.


There is truth in what you say - no advice is absolute. That said, avoiding using const saves you little (a few characters of typing) and can cost you much (in debugging - e.g. the infamous if (x = y)).

Quote:
Quote:If you need to modify the varible then you should fix your code, not just cast away the const.

If you are given code to work with, and it is a C-style program, and you are adding in C++ concepts, if you dont cast it out you have to rewrite the code - now what is easier and more efficient - rewriting C style code that works to get it to comply with some "good programming practice" or type casting it so it is *compatible* ad works the same.


This is one instance where it does make sense to const_cast away the constness. Provided you're 100% sure the function you're passing to won't try to modify the object. In general though _the_phantom_'s advice is good.

Quote:Im not trying to argue with anyone about the importance or use of const - everybody has their own views and ideas which are valid and totally acceptable and I fully respect them. However I'm just saying in my oopinion - from all my experiences that if you *truly* have data that does not need to be modified - then why are you passing it with all the techniques avalaible from OOP and C++.


I'm not following you here. Why shouldn't you pass it as const?

Quote:Pertaning to your original question - the only reason I could see to pass an argument as a const& would be if it were of some large size - at which case if you have some data type *that* large to where you need to pass a const refrence to it - then your implementations of designs are flawed. What you should be doing is passing it as a const pointer - that is why c++ gave us the -> operator to use.


It doesn't take that much to get an object large enough that passing by reference is more efficient. A couple of members and a base class is usually more than enough. What advantages do const pointers provide over references? I can't think of any. Why should we prefer pointers to references?

Quote:Just my views on the matter. Like I said, I do respect everyones views and opinions here [wink]. I guess it just depends on what you are working with.

P.S. If you were working with a char, which is 1 byte - why would you want to pass it by const refrence (4bytes)? Just an idea. It all goes back to the 3 tradeoffs of programming - speed, size, efficiency - I used to think there must be a way not to ssacrifice 2 of them, but not with the way the programming languages are designed.


(quoted for completeness - I make no comment on this part).

Enigma
Advertisement
Quote:Original post by Drew_Benton
Quote:If you need to modify the varible then you should fix your code, not just cast away the const.

If you are given code to work with, and it is a C-style program, and you are adding in C++ concepts, if you dont cast it out you have to rewrite the code - now what is easier and more efficient - rewriting C style code that works to get it to comply with some "good programming practice" or type casting it so it is *compatible* ad works the same.


Depends on how likely it is that just casting away a const is going to land you in a world of pain regarding bugs [wink] If its easier to make a change to the calling signature of the function and a couple of adaption in the function, then i'd do that, if I wasnt sure that the function wasnt going to try and modifiy things it shouldnt, then i'd probably call it using the old method and interfaces it into my code some how.
However, thats all a different sitution from designing const correctness into your code from the word go.

Quote:
Pertaning to your original question - the only reason I could see to pass an argument as a const& would be if it were of some large size - at which case if you have some data type *that* large to where you need to pass a const refrence to it - then your implementations of designs are flawed. What you should be doing is passing it as a const pointer - that is why c++ gave us the -> operator to use.


I wouldnt have said so, it depends completely on what you are doing, if I was using a raw pointer to memory than sure pointers are fine, but what about passing around large vectors? or std::strings? Both are large enuff that passing by value is going to be a killer, passing by pointer would work however you have no compiler induced garrentees regarding the use of the object, well, unless you put const in but at which point the question becomes why not use a const & to a vector/string instead of having to get a pointer to it and then dereference it at the other end to use.

Quote:
P.S. If you were working with a char, which is 1 byte - why would you want to pass it by const refrence (4bytes)? Just an idea. It all goes back to the 3 tradeoffs of programming - speed, size, efficiency - I used to think there must be a way not to ssacrifice 2 of them, but not with the way the programming languages are designed.


Well, yeah, for a single built in type using a const ref would be total over kill, as you say, its all about the right tools for the job, personally I'll take a reference over a pointer in the majority of cases and const is certainly a good idea (not just for paramters, const correctness even on fuction names etc).
Quote:Original post by Drew_Benton
I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that (besides the face of how much code it was).

...
For example, if I made a program that accepts a char*, and I used the strings c_str() function, which returns a const char*, I would have to type cast it *every time* I want to use it.


So. Let me get this straight. You advocate writing huge classes with all public data and no consts. And if perchance some other object ever returns its internal data as const, you should cast it away immediately! It'd be nice if you could #define const to be whitespace... or if VC++ had a checkbox so you could "ignore const", or even "make all data public" to allow easy integration with code written by some const-nazi.


Quote:
It gets really annoying after time to have to contiuously typecast values.


Totally! You would love Lisp.

Although the paretheses... they can be a bit much.
I think referencesare the same as pointers, but you can use them as if nothing happened and like you'd be using a normal pass-by value.
But still: Does it give a performance boost when doing it in a while(1){} loop?
Quote:Original post by ajas95
Quote:Original post by Drew_Benton
I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that (besides the face of how much code it was).

...
For example, if I made a program that accepts a char*, and I used the strings c_str() function, which returns a const char*, I would have to type cast it *every time* I want to use it.


So. Let me get this straight. You advocate writing huge classes with all public data and no consts. And if perchance some other object ever returns its internal data as const, you should cast it away immediately! It'd be nice if you could #define const to be whitespace... or if VC++ had a checkbox so you could "ignore const", or even "make all data public" to allow easy integration with code written by some const-nazi.


I did not say that I advocate writing huge classes with all public data and no consts. That would be a C struct and totally dumb [wink], as well as not being a class first of all. Like I said,*** I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that ***, as in *biiiiiggg mistake (kinfa like microsofts)*. Hopefully you can see that. Second of all, remember KISS (keep it simple, stupid). If you have huge complex classes your just asking for trouble, no matter how careful you are. That is the class design methodology I advocate. Third of all, if you understand the point of type casting from a const-to a non const to ensure *compatibility* with programs that were written with no intention of const to begin with, that is what I'm referring to. If you go and change your functions to comply with STL string, then they are dependend on its implementation. What if the end user doesnt use STL?

My last opinion on this whole matter is that I try not to *assume*. I know that you should not assume that your end user will not need to modify the data passed, who knows what the heck they will be doing [lol]. What if they did? If you are making a base class so users can dervive their own methods from it, it is not a good thing to restrict your users power to control the way the function works by making them pass a const value in order to use the function. Anyways, I'm done expressing my views, that's the beauty of programming, there is no one right way. Its been a pleasure discussing this topic! Hope to see you all around in other threads. Peace.

- Drew
Quote:Original post by Drew_Benton
I did not say that I advocate writing huge classes with all public data and no consts. That would be a C struct and totally dumb [wink], as well as not being a class first of all. Like I said,*** I once made a huge camera class with all the Get and Set methods and realized it is totally unncessary to have all of that ***, as in *biiiiiggg mistake (kinfa like microsofts)*. Hopefully you can see that.


In which case your design was fubar, I cant remember where I read it, might have been one of the Effectice C++ books, but I do remember reading once that if you have a class which requires load of get/set functions then your design is broken. The get/set functions should be doing something more than just setting and getting a varible, they should perform validation on the input and ensure sane output, otherwise as you say, it might as well be a struct so you can avoid the function call overhead.

Quote:
Second of all, remember KISS (keep it simple, stupid). If you have huge complex classes your just asking for trouble, no matter how careful you are. That is the class design methodology I advocate.


Yes, a simple class is important (Sutter adocates the 'one class, one use' system).

Quote:
Third of all, if you understand the point of type casting from a const-to a non const to ensure *compatibility* with programs that were written with no intention of const to begin with, that is what I'm referring to. If you go and change your functions to comply with STL string, then they are dependend on its implementation. What if the end user doesnt use STL?


a const std::string & can implicately construct from a char *, so its not a huge problem, also its part of the design of the class which says to the end user 'hey,if you want to use me then you have to interface in a way I understand', this ensures the end user makes use of the class in the right way and part of the whole 'design' idea [wink]

Quote:
My last opinion on this whole matter is that I try not to *assume*. I know that you should not assume that your end user will not need to modify the data passed, who knows what the heck they will be doing [lol]. What if they did? If you are making a base class so users can dervive their own methods from it, it is not a good thing to restrict your users power to control the way the function works by making them pass a const value in order to use the function.


Again, we're back to the point of design by contract, where you state the incoming data will not be modified by that function. If the end user derives the class then they are free to override/hide the old function and make their own to take its place, at which point however its not your class and your class isnt responcible for the outcome.

Taking your logic to the extreme if I was making a class which an end user might derive from then I should make everything virtual, incase they want to override it and all the members public incase they want to access them directly, and all my functions should take void * because who knows what the end user might want to do.

While its your opionion and you are entitled to it your reasons against using const correctness seem flimsy at best, poorly thought out at worst. By all means continue to code as you do, but I'm sure that you could avoid various bugs by the proper use of const (and even mutible) than you ever could by saying 'hey, who knows what the end user wants todo' *shrugs*



This topic is closed to new replies.

Advertisement