quote:
Original post by amag
Actually the get/set thingy in C# is syntactic sugar, since it allows you to do one thing you can perfectly do another way, but maybe not as neat. It doesn't violate encapsulation in the sense that you can perform things you want to when that value changes (including not allow change), which is harder when the variable is just plain public. The function is not "one for all member vars", you declare one function for each member-var you want to be able to access, so you won't expose those you don't want to expose.
So, that being the case, there is no inherent difference between that and declaring Get/Set functions, or going the reference return way - it doesn't sound like C# is really offering anything more
–
Get a stripper on your desktop!
Edited by - taliesin73 on February 23, 2001 7:26:30 AM
C++ "Addition"(wouldn't it be cool if...)
quote:
So, that being the case, there is no inherent difference between that and declaring Get/Set functions, or going the reference return way - it doesn''t sound like C# is really offering anything more
Nah, rather there''s no semantic difference between declaring the set/get or write methods like SetMyVariable()/GetMyVariable().
It''s just that you call them differently. The return reference way has a semantic difference in that you have no control of what may happen to the variable.
I don''t like notation.
Accessors usually indicate bad design. If the concept is truly encapsulated into the object, then directly accessing the data members is pointless, because the caller must be burdened with details of the inner-workings of the class. For example, look at std::vector. What does its reserve() do? Does it simply set the size? No, it sets the size, allocates additional storage, etc. Its only guarantee is that capacity will be >= than the number you passed to reserve().
If the concept is not supposed to be encapculated into the object, then accessors are unnecessary.
The point of classes (and all other code constructs, for that matter) is to encapsulate ideas by recognizing and separating abstraction levels. An abstraction layer defines dependencies between code. Hardware is also code. In assembly language, the "code" that you interface with is the set of rules defined by the design of the hardware itself: "X register holds one value, Y register holds another value, and Z instruction does task A," etc.
Any professional game programmer can tell you that different levels of code exist in a game. There is always a layer called the hardware-level, which translates simple game-level calls (like draw_bitmap(int x, int y)) into high-performance code tailored for the current hardware. The "game-level" is the highest level, where use simpler code constructs like conditional statements and high-level function calls, like input->update().
For an abstraction layer to be useful, it must expose the simplest possible interface to its services without eliminating services required by its intended users. In other words, the dependencies between levels of code must be minimized without sacrificing functionality. A single piece of software is often comprised of many levels of abstraction.
class point
{
public:
point() {}
point(const int x, const int y) : members() { x(x); y(y); }
void x(const int x) { members.x = x; }
void y(const int y) { members.y = y; }
const int x() { return( members.x ); }
const int y() { return( members.y ); }
private:
struct { int x, y; } members;
};
Accessors usually indicate bad design. If the concept is truly encapsulated into the object, then directly accessing the data members is pointless, because the caller must be burdened with details of the inner-workings of the class. For example, look at std::vector. What does its reserve() do? Does it simply set the size? No, it sets the size, allocates additional storage, etc. Its only guarantee is that capacity will be >= than the number you passed to reserve().
If the concept is not supposed to be encapculated into the object, then accessors are unnecessary.
The point of classes (and all other code constructs, for that matter) is to encapsulate ideas by recognizing and separating abstraction levels. An abstraction layer defines dependencies between code. Hardware is also code. In assembly language, the "code" that you interface with is the set of rules defined by the design of the hardware itself: "X register holds one value, Y register holds another value, and Z instruction does task A," etc.
Any professional game programmer can tell you that different levels of code exist in a game. There is always a layer called the hardware-level, which translates simple game-level calls (like draw_bitmap(int x, int y)) into high-performance code tailored for the current hardware. The "game-level" is the highest level, where use simpler code constructs like conditional statements and high-level function calls, like input->update().
For an abstraction layer to be useful, it must expose the simplest possible interface to its services without eliminating services required by its intended users. In other words, the dependencies between levels of code must be minimized without sacrificing functionality. A single piece of software is often comprised of many levels of abstraction.
quote:
Original post by null_pointer
Accessors usually indicate bad design. If the concept is truly encapsulated into the object, then directly accessing the data members is pointless, because the caller must be burdened with details of the inner-workings of the class.
Agreed. You might as well access directly in these instances, except that using accessor functions allows you to use assertions, bounds-checking and so on. Also, you don''t necessarily know what an accessor does. For example a (classic physics) vector might have a length() accessor. You don''t know if the vector is stored in polar coordinates - in which case the accessor would just return the magnitude - or if it is in rectangular coordinates, in which case it would return |x^2 + y^2|.
Personally, I would like to see a lot less of Get/Set methods in any form being used. Generally an object should know how to deal with its own internals, and noone else should.
--
Get a stripper on your desktop!
The best thing I can come up with is to do something like this:
You can add a lot of additional operators, such as ==, so you wouldn't need to cast to int before comparing it to 320.
~CGameProgrammer( );
|
You can add a lot of additional operators, such as ==, so you wouldn't need to cast to int before comparing it to 320.
~CGameProgrammer( );
Edited by - CGameProgrammer on February 23, 2001 9:45:31 PM
~CGameProgrammer( );
Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
You guys should read this thread:
http://www.flipcode.com/cgi-bin/msg.cgi?showThread=00000647&forum=general&id=-1
http://www.flipcode.com/cgi-bin/msg.cgi?showThread=00000647&forum=general&id=-1
quote:
Original post by teenytim
You guys should read this thread:
http://www.flipcode.com/cgi-bin/msg.cgi?showThread=00000647&forum=general&id=-1
Mmm, very enlightening and just as inconclusive as here ;-)
There is also an article in the C++ Users'' Report (http://www.cuj.com/experts/1902/hyslop.html), about the efficiency of accessors - it shows that inline functions were actually faster than direct access.
However this may be getting off the topic slighty. Perhaps the original suggestion isn''t such a "cool addition." (And I''m still not 100% clear on what the original suggestion was :-)
--
Get a stripper on your desktop!
Sorry about the non-clearness. I was in a rush. Usually, I try to be specific. Ok. What I meant is this: Say you have a class, and the class theoretically contains a "member". Maybe it is a Point class. Typically, a Point contains an X and a Y. As was shown in a previous post, the idea I was trying to get across, is that it would be nice if there were some way to "access" X and Y, and use bounds checking, yet still use the same syntax (i.e. point.X = 4). Does this make sense now?
class Point
{
operator X= (newX) { if (newX > minX && newX < maxX) myX = newX;}
operator =X () { return (myX); }
};
So you could do this:
point.X = 12;
And this is the code that would be used:
if (12 > point.minX && 12 < point.maxX) point.myX = 12;
But it looks like you are just assigning. Of course, this could be misleading, as if you see point.X = 12, that is the value you assume is in point.myX, right? Well, it was just a thought.
farmersckn
class Point
{
operator X= (newX) { if (newX > minX && newX < maxX) myX = newX;}
operator =X () { return (myX); }
};
So you could do this:
point.X = 12;
And this is the code that would be used:
if (12 > point.minX && 12 < point.maxX) point.myX = 12;
But it looks like you are just assigning. Of course, this could be misleading, as if you see point.X = 12, that is the value you assume is in point.myX, right? Well, it was just a thought.
farmersckn
Yesterday is the past, tomorrow is the future. Today is a gift, that is why we call it the present.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement