Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411522 Posts in 69377 Topics- by 58431 Members - Latest Member: Bohdan_Zoshchenko

April 28, 2024, 10:10:41 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)[s]Get / Set in c++?[/s] pointless debate about references and pointers
Pages: [1] 2 3 4
Print
Author Topic: [s]Get / Set in c++?[/s] pointless debate about references and pointers  (Read 10901 times)
Glaiel-Gamer
Guest
« on: April 22, 2009, 01:47:17 PM »

One of the only things in actionscript/java/c# that I miss when coding in c++ is the get and set keywords.

This is probably a bad idea, but is it possible to use some preprocessor template reference magic voodoo to emulate the same behavior in a c++ class?

Again I'm fine making stuff publicly accessible, but sometimes it'd be nice to do stuff that is a computer value and treat it like a variable (like length on a vector class, in my flash class I can do vector.length += 42 and it increases its length by 42 even though length isn't stored on the object).

It's probably more trouble than it's worth to figure this out in c++ though to save a little extra typing.
« Last Edit: May 03, 2009, 03:42:54 PM by Glaiel-Gamer » Logged
increpare
Guest
« Reply #1 on: April 22, 2009, 01:53:15 PM »

i don't know of any good way to automatically do accessors w/ templates (or otherwise) + C++; you generally just have to do them manually.
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #2 on: April 22, 2009, 01:55:35 PM »

I guess you could like.. overload = in some SettableGettable superclass and something crazy with that. That's kind of crazy though.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
Impossible
Level 3
***



View Profile
« Reply #3 on: April 22, 2009, 02:24:21 PM »

Its possible through various template magics. http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4031 is one example.  Google "C++ properties" and you'll find a few implementations of it.  Not sure how well any of them work though.
Logged
birdcloud
Level 0
**



View Profile
« Reply #4 on: April 23, 2009, 03:25:36 AM »

You could write a macro like

Code:
#define PROPERTY(type,name) \
private: \
  type name; \
public: \
  void set_##name(type const& name##_) { name = name##_; } \
  type& get_##name() { return name; } \

which relies on operator=() for your copying strategy, or a variant for pointers like

Code:
#define PTR_PROPERTY(type,name) \
private: \
  type * name; \
public: \
  void set_##name(type * name##_) { delete name; name = new type(* name##_); } \
  type * get_##name() { return name; } \

to delete the old pointed-to value and copy the new pointed-to value instead of merely its address

You'd use these like:

Code:
class X {
  PROPERTY(int, a)
  PROPERTY(int, b)
  PTR_PROPERTY(int, c)

public:
  X(int A, int B): a(A), b(B), c(0) { }
  ~X() { delete c; }
 
  void print() { printf("%i %i %i\n", a, b, *c); }
};

int main() {
  X x(3, 4);
  x.set_a(2 * x.get_b());
 
  int my_c = 10;
  x.set_c(&my_c);
  my_c = 99; // won't change value pointed to by x's c
 
  x.print(); // output is 8 4 10
  return 0;
};

I don't know, I probably wouldn't bother.

As for vector.length += 42, that's kind of confusing. I'd much rather write vector.extend(42) or something. The += looks simple but must hide a normalization, i.e., a square root and a division.

EDIT: I suppose one could also write the macro to take other macros that generate the getter & setter bodies. Dang, working this out is wanting me to see how much crazy macro sugar I can lay on C++ like this for no good reason whatsoever.
« Last Edit: April 23, 2009, 05:11:01 AM by oligophagy » Logged
Movius
Guest
« Reply #5 on: April 23, 2009, 08:24:34 AM »

One of the only things in actionscript/java/c# that I miss when coding in c++ is the get and set keywords.

This is probably a bad idea, but is it possible to use some preprocessor template reference magic voodoo to emulate the same behavior in a c++ class?

Again I'm fine making stuff publicly accessible, but sometimes it'd be nice to do stuff that is a computer value and treat it like a variable (like length on a vector class, in my flash class I can do vector.length += 42 and it increases its length by 42 even though length isn't stored on the object).

It's probably more trouble than it's worth to figure this out in c++ though to save a little extra typing.
How long has Java had such voodoo keywords? I know it's changed a lot recently, (I haven't done any major projects with it for a couple of years,) but I always thought manual getters & setters were a necessity
Logged
raigan
Level 5
*****


View Profile
« Reply #6 on: April 23, 2009, 12:27:51 PM »

I know this doesn't help you much right now, but just FYI my strategy when using AS3 or C# is to try and only use language features which are common/standard (i.e no introspection, manual get/set, etc), this makes porting a lot simpler Smiley

Logged
Kaelan
Level 1
*


Malcontent


View Profile WWW
« Reply #7 on: April 23, 2009, 02:26:17 PM »

VC++ only getter/setter support:
http://msdn.microsoft.com/en-us/library/yhfk0thd(VS.80).aspx

Also, in some cases you can do this by creating fields of a special templated type that is set up to automatically detect assignments and run your accessor, through careful use of automatic type conversions and such. But I don't think it's worth going to that much trouble unless it significantly simplifies your codebase, since debugging templates is a bitch. For an example of how this technique can be applied, look at smart pointer types (std::auto_ptr, boost::shared_ptr, etc) - they are effectively pointers with semiautomatic getters/setters.

So I'd go with the VC++ support if you're only targeting win32, and otherwise, just stick with plain ol' C++. I find foo.getBar() and foo.setBar(x) to be pretty tolerable in most cases, anyway, as long as you don't introduce monstrosities like out parameters into the equation. (This is a strong argument for the use of exceptions)
Logged

Eclipse
Level 10
*****


0xDEADC0DE


View Profile WWW
« Reply #8 on: May 01, 2009, 01:23:04 AM »

do an inline function called set and one called get, make the variables private and you're gold.
Logged

<Powergloved_Andy> I once fapped to Dora the Explorer
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #9 on: May 01, 2009, 04:40:12 AM »

I wonder if it's blasphemy to say "just make all the members you want accessible public". I'm so used to just not caring about public/private/protected encapsulation in Python and tend to see more worth in encapsulation via message passing or event systems, which is a bit higher-level and a bit more involved in the system as a whole rather than particular classes.
Logged

Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #10 on: May 01, 2009, 05:18:19 AM »

I wonder if it's blasphemy to say "just make all the members you want accessible public".
It is, and you'll find out why when that integer variable you carelessly made public and is being used all around the codebase by all and sundry suddenly needs to change its internal implementation to a floating point number, and loads of code has to change as a result.

Consider:
Code:
class Jug
{
  public:
    int FillLevel; // fill level from 1 to 10
    void Update(); // updates the fill level of the jug. Asserts or even crashes if FillLevel is < 1 or > 10
}
Immediately you've exposed a problem with FillLevel being public, in that people can set the number to whatever they like (sure, you can put a check in the Update() function to protect against this, but why do that check every update when it could be done only when FillLevel is changed?)
But now you want to change FillLevel to a floating point number, because the artist wants the graphic for the jug to fill up smoothly and not just jump from 1 to 2 to 3 etc. Looking through the code, you find 40 files that reference Jug::FillLevel as an int. You have to go through all of those 40 files and change the code that references this value, probably having to mess with a bunch of code you know nothing about and may never have even seen before. And that's assuming to actually have access to these files.

Consider instead:

Code:
class Jug
{
  public:
    int GetFillLevel() { return mFillLevel;  }// fill level from 1 to 10
    void SetFillLevel(int level) { if (level <1) level = 1; if (level > 10) level = 10; mFillLevel = level; }
    void Update(); // updates the fill level of the jug. Asserts if mFillLevel is < 1 or > 10
  private:
    int mFillLevel;
}

Now you want to change it to a float.


Code:
class Jug
{
  public:
    int GetFillLevel() { return (int)mFillLevel;  }// fill level from 1 to 10
    void SetFillLevel(int level) { if (level <1) level = 1; if (level > 10) level = 10; mFillLevel = level; }
    void Update(); // updates the fill level of the jug. Asserts if mFillLevel is < 1 or > 10
  private:
    float mFillLevel;
}

Two changes. And you didn't have to tell anyone who called GetFillLevel() about it, or change their code, as their code will still run the same way.

And this is just for int->float. Imagine if that member was a class type that you wanted to change.
Logged

muku
Level 10
*****


View Profile
« Reply #11 on: May 01, 2009, 05:23:57 AM »

I wonder if it's blasphemy to say "just make all the members you want accessible public".

Many people will berate you for that, but considering how many real-world getters/setters really do nothing else but get and set a private member variable, it can work for some members. It depends a lot on the actual class; sometimes you have a very strong idea of what a class is trying to encapsulate, and it is easy to define a clean interface to it. Other times it's not so clear cut.

The real problem is C++ forcing you to decide from the get-go whether a member will be a variable or a pair of getter/setter calls. It shouldn't be that way; in a well-designed language, you should be able to start out with public member variables and convert them to properties without having to change the class's public interface.
Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #12 on: May 01, 2009, 05:33:48 AM »

that was your leet post!

Logged

muku
Level 10
*****


View Profile
« Reply #13 on: May 01, 2009, 05:41:28 AM »

Oh shit and I missed it completely! :D
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #14 on: May 01, 2009, 09:34:20 AM »

I think the real benefit of getter/setters (in AS anyway) is being able to execute code when you get or set a variable, rather than access to private members.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
JoeHonkie
Level 8
***


RIP Major Sebastian Bludd


View Profile WWW
« Reply #15 on: May 01, 2009, 10:06:34 AM »

I think the real benefit of getter/setters (in AS anyway) is being able to execute code when you get or set a variable, rather than access to private members.

I'm teaching myself C# (well, a book is teaching me) and I found this feature to be really, really neat.
Logged
muku
Level 10
*****


View Profile
« Reply #16 on: May 01, 2009, 11:36:13 AM »

That's the only purpose of properties, no? If you just wanted to expose private member variables, you could just make them public.
Logged
Shuger
Level 0
**


View Profile
« Reply #17 on: May 01, 2009, 11:53:17 AM »

I make get/set functions for all variables accessed from outside the class. Just in case they will become some more advanced property later on. In which case i will just need to reimplement get/set body, and won't have to refactor half of the project changing object.x = 0, to object.setX(0)... Still, agreed it's pretty annoying and time wasting Wink Just remember that you don't have to make it for all classes, for example a simple vector class which has only x and y variables and most functionality can be implemeted threw overloaded operators.
Logged
Ravine
Level 0
**


View Profile
« Reply #18 on: May 01, 2009, 11:59:13 AM »

(damn i reread my post, and it sound really lame, like some "mister know it all" stuff. Please dont hold it against me, that wasnt my goal)

That's the only purpose of properties, no? If you just wanted to expose private member variables, you could just make them public.
Well, short answer is no (IMO)

Longer answer. Properties are just a syntactic sugar for the "old" GetStuff() SetStuff() methods. Basically, it's a mechanism to comply with the concept of encapsulation in OOP. Wich means, thats there are risks in setting public the one you want to show.

First case : you want to give access in reading, but not in writing.
Code:
private int _age;

public int Age
{
   get { return _age; }
}
problem solved. They can access in reading, not in writing.

Second case : you want to give access in reading, and internally in writing
Code:
private int _age;

public int Age
{
   get { return _age; }
   private set { _age = value; }
}
easy, right ?

Third case : you want to give access in reading, writing, AND perform some interesting stuff inside. (real code)
Code:
public ThreatLevel Threat
{
   get { return threat;}
   private set
   {
       if (value != threat)
       {
          threat = value;
          threatStateChanged = true;
       }
   }
}

What is interesting in this case, is for modularity and reuse of code. With the properties (or getter/setter), code which use those does not have to change. You avoid refactoring because you dont change the way it's exposed. You only change what happened inside.

In my opinion, there's no reason to not use properties, or getter/setter, UNLESS you know why, and the why is a GOOD reason not to use them. Public access may be dangerous; not always, but it can be.

« Last Edit: May 01, 2009, 12:03:14 PM by Ravine » Logged
muku
Level 10
*****


View Profile
« Reply #19 on: May 01, 2009, 12:32:34 PM »

I know, Ravine. My point is that in a language supporting properties, you can safely start out with public members if it fits your design, and only when you realize that your needs are more specific (read-only, execute some code on write...) do you need to convert them to actual properties. There's no harm in that because the class's users don't need to know whether they're dealing with a member or a property.
Logged
Pages: [1] 2 3 4
Print
Jump to:  

Theme orange-lt created by panic