How's this for OOP?
-
Stingray uses this in their Objective Grid package:
public:
int & Width() {return m_iWidth;}so, you can do silly things like this:
thing.Width() = thing.Width() / 2;
i can't decide if this is good, bad or just clever. -c ------------------------------ Smaller Animals Software, Inc. http://www.smalleranimals.com
-
Stingray uses this in their Objective Grid package:
public:
int & Width() {return m_iWidth;}so, you can do silly things like this:
thing.Width() = thing.Width() / 2;
i can't decide if this is good, bad or just clever. -c ------------------------------ Smaller Animals Software, Inc. http://www.smalleranimals.com
public:
int& Width() {return m_iWidth;}>i can't decide if this is good, bad or just clever And I can't imagine a more useless function than this one. How can I get direct access to a private/protected member... My vote: bad ;P Max
-
Stingray uses this in their Objective Grid package:
public:
int & Width() {return m_iWidth;}so, you can do silly things like this:
thing.Width() = thing.Width() / 2;
i can't decide if this is good, bad or just clever. -c ------------------------------ Smaller Animals Software, Inc. http://www.smalleranimals.com
Two thumbs down. It breaks encapsulation - might as well make it a public variable.
-
public:
int& Width() {return m_iWidth;}>i can't decide if this is good, bad or just clever And I can't imagine a more useless function than this one. How can I get direct access to a private/protected member... My vote: bad ;P Max
The function in this context is indeed useless, but what if you want to check for valid values in a Get/Set function? void SetSomeValue(int nValue) { ASSERT(nValue > 0 && nValue < 10); m_iValue = nValue; } That makes a little more sense and is fool-proof at the same time :) -- Alex Marbus www.marbus.net
-
Two thumbs down. It breaks encapsulation - might as well make it a public variable.
Two thumbs down. It breaks encapsulation - might as well make it a public variable. It acts as a public variable, but you can also put a breakpoint so you can see who & when get/set the variable. - - - - - - - - - - - - - - - - - - Memory leaks is the price we pay \0 01234567890123456789012345678901234
-
Stingray uses this in their Objective Grid package:
public:
int & Width() {return m_iWidth;}so, you can do silly things like this:
thing.Width() = thing.Width() / 2;
i can't decide if this is good, bad or just clever. -c ------------------------------ Smaller Animals Software, Inc. http://www.smalleranimals.com
Chris There are some cool ideas to be gleaned from the Stingray code, (Code make terse on purpose, NO FLAMING!), returning the reference of an object can be quite handy. I've used this before: CScreen screen; screen.SetBackColor(RGB(0,0,255)) .SetForeColor(RGB(128,0,0)); Nice for setting multiple properties on an object. Norm class CScreen() { public: CScreen& SetBackColor(COLORREF cr) { m_crBK = cr; return *this; } CScreen& SetForeColor(COLORREF cr) { m_crFR = cr; return *this; } protected: COLORREF m_crBk; COLORREF m_crFR; };
-
Stingray uses this in their Objective Grid package:
public:
int & Width() {return m_iWidth;}so, you can do silly things like this:
thing.Width() = thing.Width() / 2;
i can't decide if this is good, bad or just clever. -c ------------------------------ Smaller Animals Software, Inc. http://www.smalleranimals.com
Good: If used right, it can make the implementation of THAT class (and possible of derived classes, but this is questionable) more readable. Bad: It is public, so you don't give a chance to the object to act on the state change (and lots of other reasons, like validation, etc). Also I don't like the name. It does't suggest that this function gives you a reference. This is a fortunate case because Width is a noun, but there are cases when the word used can be both a noun or a verb, creating unnecessary confusion.
thing.Size().cx /= 2;
is not that cool, right? What about this? :public:
int GetWidth() const {return m_bState ? m_iWidth1 : m_iWidth2;}
void SetWidth(const int iWidth); // implemented elsewhere
protected:
int& RefWidth() {return m_bState ? m_iWidth1 : m_iWidth2;} -
Chris There are some cool ideas to be gleaned from the Stingray code, (Code make terse on purpose, NO FLAMING!), returning the reference of an object can be quite handy. I've used this before: CScreen screen; screen.SetBackColor(RGB(0,0,255)) .SetForeColor(RGB(128,0,0)); Nice for setting multiple properties on an object. Norm class CScreen() { public: CScreen& SetBackColor(COLORREF cr) { m_crBK = cr; return *this; } CScreen& SetForeColor(COLORREF cr) { m_crFR = cr; return *this; } protected: COLORREF m_crBk; COLORREF m_crFR; };
Exactly! The whole idea behind Objective Grid design is that user can build expressions like this: SetStyleRange(CGXRange(9, 1, 11, 8), CGXStyle().SetControl(IDS_CTRL_CAPSEDIT).SetValue("Some text").SetInterior(RGB(192,192,192)); ); You can like it or not, call it non-OOP etc. But it is consistent, and once you are familiar with it, it's quite easy to manage. Win32/ATL/MFC Developer Oslo, Norway
-
Exactly! The whole idea behind Objective Grid design is that user can build expressions like this: SetStyleRange(CGXRange(9, 1, 11, 8), CGXStyle().SetControl(IDS_CTRL_CAPSEDIT).SetValue("Some text").SetInterior(RGB(192,192,192)); ); You can like it or not, call it non-OOP etc. But it is consistent, and once you are familiar with it, it's quite easy to manage. Win32/ATL/MFC Developer Oslo, Norway
This particular idiom has nothing to do with OOP - well, I suppose you couldn't do it with straight C, of course, but it's neither good nor bad from a design standpoint - it changes nothing but the syntax. Personally I find it makes the code hard to read, but it's not a fatal flaw.
-
Good: If used right, it can make the implementation of THAT class (and possible of derived classes, but this is questionable) more readable. Bad: It is public, so you don't give a chance to the object to act on the state change (and lots of other reasons, like validation, etc). Also I don't like the name. It does't suggest that this function gives you a reference. This is a fortunate case because Width is a noun, but there are cases when the word used can be both a noun or a verb, creating unnecessary confusion.
thing.Size().cx /= 2;
is not that cool, right? What about this? :public:
int GetWidth() const {return m_bState ? m_iWidth1 : m_iWidth2;}
void SetWidth(const int iWidth); // implemented elsewhere
protected:
int& RefWidth() {return m_bState ? m_iWidth1 : m_iWidth2;}I hate to get picky (but I will anyway!), but this simple example reveals a VERY common theoretical issue in C and C++ code - "width" is a mesurement of a physical attribute - it cannot be negative in any valid sense, so 'int' is a poor choice as either the internal or public representation. It should be unsigned. Always. Without exception. This problem occurs again and again in C and C++ code because the compiler will cheerfully (and sometimes very unexpectedly) convert between signed and unsigned. So programmers don't worry too much about it, and 'unsigned int' takes longer to type! So, we have dates stored as ints (what exactly does a negative day represent?), and everything else as well. And (just to add a final point) this leads to another 'common' practice - using '-1' ot indicate 'not valid'. That's just being sloppy.