OOP??
-
I agree with some of the gets/sets arguments and use them in my code.. That said, there also can be times where the "sloppiness" that is public member variables, would much simplify dealing with legacy code... For instance, I found myself using an MFC extension dll, that is very low in the list of a long heirarchy of DLLs for an existing application... The original developers had not foreseen the uses of setting a particular variable, and so had not exposed any gets/sets for it.. Now had this variable been public so I could have set it directly, no problems would have occured, and by using sloppy code, I could have used the existing library base, but since it wasn't, the "header file was hit" and all the dlls up the heirarchy chain had to be recompiled (over 30 of them), to be compatible with my new "handy" get/set.... Just one case, but.... On another little note... The argument that you might "Accidently" set a public member variable, disturbs me a little as a reason for Gets/Sets... If you might "Accidently" set the member variable, then you also might "accidently" call the Set function, either way you dont know what the heck your doing, with that particular class!! So if that is the worry, then learn the code!! The Black Box that is OOP is a good idea.. But we all know, that more than likely you are going to know what's going on "under the hood", in order to use more advanced classes. You normally have to read the source code, to see if a particular function handles exactly what you want.. So in some cases the "Black Box" gets it's side kicked in once in a while. That's the nature of the beast. WE gotta know how something works, and if its working right. And even most programmer's that stand by and brag up OOP, end up having exceptions of their own that they overlook, in order to continue the argument. Cool B:cool:
>[...] Now had this variable been public so I could have set it directly, >no problems would have occured [...] ...but obviously the variable is private so you have the same trouble. So what's the difference in making a variable public or writing get/set methods? In the same manner I could say "If there were get/set methods...". Sorry, I don't see any advantages. >[...]and all the dlls up the heirarchy chain had to be recompiled (over 30 of them), >to be compatible with my new "handy" get/set So what? I would say that the actually problem is a missing feature in the base class. So if you extend your base class with an additional feature (be it through get/set methods or by simply making a variable public) then a recompile is the logical consequence... >[...] then you also might "accidently" call the Set function [...] Yes, but then you can return an error code or you could raise an exception, but your class remains in a valid state... >[...]So if that is the worry, then learn the code!! :confused: CU Max
-
>[...] Now had this variable been public so I could have set it directly, >no problems would have occured [...] ...but obviously the variable is private so you have the same trouble. So what's the difference in making a variable public or writing get/set methods? In the same manner I could say "If there were get/set methods...". Sorry, I don't see any advantages. >[...]and all the dlls up the heirarchy chain had to be recompiled (over 30 of them), >to be compatible with my new "handy" get/set So what? I would say that the actually problem is a missing feature in the base class. So if you extend your base class with an additional feature (be it through get/set methods or by simply making a variable public) then a recompile is the logical consequence... >[...] then you also might "accidently" call the Set function [...] Yes, but then you can return an error code or you could raise an exception, but your class remains in a valid state... >[...]So if that is the worry, then learn the code!! :confused: CU Max
Neat... Ummm... Yeah it was a flaw, in the base class.. Something that was not foreseen... Thats what I said.. But obviously causing a complete rebuild of a product that has been published for a couple years, is not a shrug off type of thing... It broke down the whole OOP way of thinking.. I had to rebuild a whole system in order to "re-use" code in a completely different application... But "So what??" Hmmmm.... And if you accidently call the Set function with a valid argument the object's state is still changed!!! I agree that there is validation that CAN BE done in the Get/Set, but in a majority of situations, its not!!! And ULTIMATELY for this "Accidental" code to work correctly, it takes the developer knowing what is going on.. So what if you throw an exception or error, Nothing will happen at this point, when obviously something was intended... Still Broken Code, it just degrades gracefully, but still doesnt work!!! Hmmm.... So Now me :confused: Cool B
-
I agree with some of the gets/sets arguments and use them in my code.. That said, there also can be times where the "sloppiness" that is public member variables, would much simplify dealing with legacy code... For instance, I found myself using an MFC extension dll, that is very low in the list of a long heirarchy of DLLs for an existing application... The original developers had not foreseen the uses of setting a particular variable, and so had not exposed any gets/sets for it.. Now had this variable been public so I could have set it directly, no problems would have occured, and by using sloppy code, I could have used the existing library base, but since it wasn't, the "header file was hit" and all the dlls up the heirarchy chain had to be recompiled (over 30 of them), to be compatible with my new "handy" get/set.... Just one case, but.... On another little note... The argument that you might "Accidently" set a public member variable, disturbs me a little as a reason for Gets/Sets... If you might "Accidently" set the member variable, then you also might "accidently" call the Set function, either way you dont know what the heck your doing, with that particular class!! So if that is the worry, then learn the code!! The Black Box that is OOP is a good idea.. But we all know, that more than likely you are going to know what's going on "under the hood", in order to use more advanced classes. You normally have to read the source code, to see if a particular function handles exactly what you want.. So in some cases the "Black Box" gets it's side kicked in once in a while. That's the nature of the beast. WE gotta know how something works, and if its working right. And even most programmer's that stand by and brag up OOP, end up having exceptions of their own that they overlook, in order to continue the argument. Cool B:cool:
This from "Microsoft Foundation Class Library Development Guidelines": [quote]
Use "Accessor" (Get/Set) functions when they add value
There is a philosophy of class design that suggests that all data members should be private or protected and that accessor functions should be used to change the values in those data members. MFC uses public data members instead, frequently offering both a public data member and an accessor function for use by the developer. For example, class CWnd provides both a public data member, CWnd::m_hWnd, and an accessor function, CWnd::GetSafeHwnd. Depending on the needs of a particular application, a developer might use the data member or the member function, or both. More often, MFC uses accessor functions in significant operations such as setting and retrieving style settings, returning pointers, and obtaining values used in other operations. We encourage developers who are writing MFC-friendly classes to use public data members as often as possible, and reserve accessor functions for operations that do more than simply change values in a data member, such as incrementing a counter or updating another function. [end quote] When I first read this I was shocked - I still make a point of pontificating that "MFC is NOT object oriented" to any poor soul who might ask me how to put a bitmap in a button. But, real OOP, like const correctness, can be hmmm... 'less easy' to work with? MFC is pretty good at letting you do what you want, once you're... assimilated?
-
This from "Microsoft Foundation Class Library Development Guidelines": [quote]
Use "Accessor" (Get/Set) functions when they add value
There is a philosophy of class design that suggests that all data members should be private or protected and that accessor functions should be used to change the values in those data members. MFC uses public data members instead, frequently offering both a public data member and an accessor function for use by the developer. For example, class CWnd provides both a public data member, CWnd::m_hWnd, and an accessor function, CWnd::GetSafeHwnd. Depending on the needs of a particular application, a developer might use the data member or the member function, or both. More often, MFC uses accessor functions in significant operations such as setting and retrieving style settings, returning pointers, and obtaining values used in other operations. We encourage developers who are writing MFC-friendly classes to use public data members as often as possible, and reserve accessor functions for operations that do more than simply change values in a data member, such as incrementing a counter or updating another function. [end quote] When I first read this I was shocked - I still make a point of pontificating that "MFC is NOT object oriented" to any poor soul who might ask me how to put a bitmap in a button. But, real OOP, like const correctness, can be hmmm... 'less easy' to work with? MFC is pretty good at letting you do what you want, once you're... assimilated?
But what is the point of writing Get/Set methods if all they do is replicate the code you would have written directly to access a public variable ? I write Get/Set methods whenever I have reason to validate the input, but I'd never bother with void SetFlag(bool b) { m_Flag = b; } , I mean, where is the point in that ? Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
-
But what is the point of writing Get/Set methods if all they do is replicate the code you would have written directly to access a public variable ? I write Get/Set methods whenever I have reason to validate the input, but I'd never bother with void SetFlag(bool b) { m_Flag = b; } , I mean, where is the point in that ? Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
I don't think I was making a point in that message, but here's my 2 cents. If I'm desingning a class, I try to follow some disciplines at the outset, knowing that I will inevitably introduce entropy as I hack my way through the implementation. Sort of 'follow the rules until you have to break them'. So, unless the class is the base of a heirarchy, all private data membs, else protected (where appropo) and accessor functions. Thus a (virtual) SetFlag() makes sense - as a class may evolve down the tree wherein setting this flag has other side effects - and there'll be less cleanup to do when that happens. But I'm not telling you anything you don't know. I think maybe the point of that post was to get at the feeling that my C++ skills and approach have been somewhat sullied by working with the MFC - anyone know of an OOP OS I can play with? ---- "The opinions expressed herein are not necessarily those of anyone's yummi sushi pyjamas"
-
This from "Microsoft Foundation Class Library Development Guidelines": [quote]
Use "Accessor" (Get/Set) functions when they add value
There is a philosophy of class design that suggests that all data members should be private or protected and that accessor functions should be used to change the values in those data members. MFC uses public data members instead, frequently offering both a public data member and an accessor function for use by the developer. For example, class CWnd provides both a public data member, CWnd::m_hWnd, and an accessor function, CWnd::GetSafeHwnd. Depending on the needs of a particular application, a developer might use the data member or the member function, or both. More often, MFC uses accessor functions in significant operations such as setting and retrieving style settings, returning pointers, and obtaining values used in other operations. We encourage developers who are writing MFC-friendly classes to use public data members as often as possible, and reserve accessor functions for operations that do more than simply change values in a data member, such as incrementing a counter or updating another function. [end quote] When I first read this I was shocked - I still make a point of pontificating that "MFC is NOT object oriented" to any poor soul who might ask me how to put a bitmap in a button. But, real OOP, like const correctness, can be hmmm... 'less easy' to work with? MFC is pretty good at letting you do what you want, once you're... assimilated?
I think you're confusing OOP with other things. const correctness has nothing to do with OOP, and everything to do with making your interfaces safe. People complain about how direct access of members is breaking encapsulation, but encapsulation is designed to insulate the programmer from changes. Microsoft makes many members public, but many of them are considered "implementation defined" and thus subject to change. If you look at many of the MFC header files, you'll see "// Implementation" which means that anything after that is considered subject to change. Everything above it is guaranteed not to change, so violating encapsulation is meaningless, since doing so doesn't cause any harm (other than teaching people that doing so is good practice). In an interface that is set in stone and will never change, there is nothing wrong with public variables. Rules of thumb that say to ALWAYS use certain techniques simply aren't always the best way. I agree that in user code, unless you've thoroughly designed the interface and know for a fact it won't change, getter/setters are the better way to go.
-
Neat... Ummm... Yeah it was a flaw, in the base class.. Something that was not foreseen... Thats what I said.. But obviously causing a complete rebuild of a product that has been published for a couple years, is not a shrug off type of thing... It broke down the whole OOP way of thinking.. I had to rebuild a whole system in order to "re-use" code in a completely different application... But "So what??" Hmmmm.... And if you accidently call the Set function with a valid argument the object's state is still changed!!! I agree that there is validation that CAN BE done in the Get/Set, but in a majority of situations, its not!!! And ULTIMATELY for this "Accidental" code to work correctly, it takes the developer knowing what is going on.. So what if you throw an exception or error, Nothing will happen at this point, when obviously something was intended... Still Broken Code, it just degrades gracefully, but still doesnt work!!! Hmmm.... So Now me :confused: Cool B
There is a solution which avoids rebuilding the old code:
// old code
class A
{
//...
private:
X m_xHiddenThing;
};// your code
class B : public class A
{
public:
const X& GetThing() const {return m_xHiddenThing;}
void GetCopyThing(X& xThing) const {xThing = m_xHiddenThing;}
void SetThing(const X& xThing {m_xHiddenThing = xThing;}
};//... A a; X xThingT = ((B\*) &a)->GetThing(); ((B\*) &a)->SetThing(xThingT);
The OOP purists here will be horrified, but there are cases when you really need to have direct access to a member because the designer of the class didn't anticipated your need. The best example is a class library which is very hard if not impossible to rebuild (like MFC). The
a
object is allocated here on the stack for simplicity, but most likely it is itself a membef of another object created inside the library. -
I agree with some of the gets/sets arguments and use them in my code.. That said, there also can be times where the "sloppiness" that is public member variables, would much simplify dealing with legacy code... For instance, I found myself using an MFC extension dll, that is very low in the list of a long heirarchy of DLLs for an existing application... The original developers had not foreseen the uses of setting a particular variable, and so had not exposed any gets/sets for it.. Now had this variable been public so I could have set it directly, no problems would have occured, and by using sloppy code, I could have used the existing library base, but since it wasn't, the "header file was hit" and all the dlls up the heirarchy chain had to be recompiled (over 30 of them), to be compatible with my new "handy" get/set.... Just one case, but.... On another little note... The argument that you might "Accidently" set a public member variable, disturbs me a little as a reason for Gets/Sets... If you might "Accidently" set the member variable, then you also might "accidently" call the Set function, either way you dont know what the heck your doing, with that particular class!! So if that is the worry, then learn the code!! The Black Box that is OOP is a good idea.. But we all know, that more than likely you are going to know what's going on "under the hood", in order to use more advanced classes. You normally have to read the source code, to see if a particular function handles exactly what you want.. So in some cases the "Black Box" gets it's side kicked in once in a while. That's the nature of the beast. WE gotta know how something works, and if its working right. And even most programmer's that stand by and brag up OOP, end up having exceptions of their own that they overlook, in order to continue the argument. Cool B:cool:
>>If you might "Accidently" set the member variable, then you also might "accidently" call the Set function<< I don't know about this. I think it's a lot easier to accidently code dlg.WindowText = "Hello world!" than dlg.SetWindowText("Hello World!") especially for someone coming from a VB background where we have built in Property Get/Set methods that gives us the syntax of a public variable but the control of get/set methods. When I'm writting Java or C++, I never expose public members. I always use get/set. Sure it's tedious, but I just do it anyway. And it leaves open the ability to change business rules in the future without breaking existing implementations. Jason Gerard MCSD, MCSE Technology Point International, Inc
-
But what is the point of writing Get/Set methods if all they do is replicate the code you would have written directly to access a public variable ? I write Get/Set methods whenever I have reason to validate the input, but I'd never bother with void SetFlag(bool b) { m_Flag = b; } , I mean, where is the point in that ? Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
The point is the access to the variable is in one place. The access to the variable can be value or range limited/validated. The access to the variable can be augmented, overridden, logged etc. You can put breakpoints on it. All in one place. Very useful if the application you are working on has 2 million lines of code and 40 or more developers in 3 continents. Stephen Kellett
-
There is a solution which avoids rebuilding the old code:
// old code
class A
{
//...
private:
X m_xHiddenThing;
};// your code
class B : public class A
{
public:
const X& GetThing() const {return m_xHiddenThing;}
void GetCopyThing(X& xThing) const {xThing = m_xHiddenThing;}
void SetThing(const X& xThing {m_xHiddenThing = xThing;}
};//... A a; X xThingT = ((B\*) &a)->GetThing(); ((B\*) &a)->SetThing(xThingT);
The OOP purists here will be horrified, but there are cases when you really need to have direct access to a member because the designer of the class didn't anticipated your need. The best example is a class library which is very hard if not impossible to rebuild (like MFC). The
a
object is allocated here on the stack for simplicity, but most likely it is itself a membef of another object created inside the library.Cristi, Your code will not compile because m_xHiddenThing is a private variable and can be accessed only within the type it is declared in - class A. If it was declared using protected modifier then it would be possible to use the suggested code. That is why you have to be very careful while declaring private members without exposing them through protected or public functions Regards, Andrei Zenkovitch
-
Cristi, Your code will not compile because m_xHiddenThing is a private variable and can be accessed only within the type it is declared in - class A. If it was declared using protected modifier then it would be possible to use the suggested code. That is why you have to be very careful while declaring private members without exposing them through protected or public functions Regards, Andrei Zenkovitch
Thanks for the correction, Andrei :) Indeed, the hidden member must be protected for this to work. As I said, this trick is sometimes useful for some MFC classes with protected data members with no way to access them. You can't rebuild the MFC libs, so this can be a solution. Cheers, Cristi
-
The point is the access to the variable is in one place. The access to the variable can be value or range limited/validated. The access to the variable can be augmented, overridden, logged etc. You can put breakpoints on it. All in one place. Very useful if the application you are working on has 2 million lines of code and 40 or more developers in 3 continents. Stephen Kellett