Jump to content
  • Advertisement
Sign in to follow this  
shotgunnutter

Read only public members of class.

This topic is 3823 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wonder if this is a good alternative to using get/set methods. I'm currently writing a class to do explosions, which has quite a lot of variables which need to be read by other classes within different subsystems. Suppose I was to do this:
class roFloat
{
private:
  float value;
  bool locked;
public:
  roFloat(){unlock()};
  roFloat(float V){value=V; lock();};
  void lock();
  void unlock();
};

//overloaded operators for read access: always work
roFloat operator== ...
roFloat operator+ ...
roFloat operator- ...


//overloaded operators for write access: only work if instance is unlocked.
roFloat operator= ----throw assertion to warn programmer
roFloat operator+= ----throw assertion to warn programmer
...etc.



Is there a commonly accepted alternative to doing this? I've certainly never seen anything like it. [edit] Oh, and don't worry, I'm wearing my bullet proof shoes. [lol] [Edited by - shotgunnutter on December 30, 2007 3:48:33 PM]

Share this post


Link to post
Share on other sites
Advertisement

class Test
{
private:

int member;

public:

const int& public_member;

Test() : public_member(member) {}

};

Share this post


Link to post
Share on other sites
Quote:
Original post by hydroo
*** Source Snippet Removed ***


That implementation still adds an extra member variable. I'm looking to avoid something like this:


class explosion
{
private:
float age
float force_distribution_matrix[3][3][3];
float force;
float radius;
float force_left;
float temperature;
...plus some physics engine specific objects

public:
float get_age();
float * get_force_distribution_matrix();
float get_force();
float get_radius;
float get_energy_left();
float get_temperature();

};




instead having something like this:


class explosion
{
private:

public:
roMember<float>age;
roMember<float>force;
roMember<float> * force_distribution_matrix;
...
};




so that the first time a public member is set, it then locks. Take the force distribution matrix, for example, in the constructor:


force_distro_matrix[0][0][0]=some_value;
force_distro_matrix[1][0][0]=some_value;
force_distro_matrix[2][0][0]=some_value;
force_distro_matrix[3][0][0]=some_value;




then, the AI, the Collision system, the game logic, and the renderer are all able to access the force distrobutiuon matrix by direct naming. Anybody subsequently abusing the system, and trying to edit the public members, would get a failed assertion.

The question, basically, is would this implementation be a bad idea? I don't have any professional c++ experience to apply here.

[Edited by - shotgunnutter on December 30, 2007 4:04:34 PM]

Share this post


Link to post
Share on other sites
You could also make those functions friend of your class.

Or make them public? I mean, if you look for a way to read and write the variables without getters/setters, they'll become public anyway, or else you can make only that what's allowed to read/write friend.

Or make something like this?


class Foo
{
private:
int bar;

public:
const int& getBar() const { return bar; }
};



Edit: after the other reply from shotgunnutter in the middle it seems that I answered something wrong.

Did you just answer your own question with the part under "instead having something like this"? Give your templated ro's the necessary operator=, operator float(), etc..., and you can get the behaviour you want?

Share this post


Link to post
Share on other sites
Quote:
Original post by Lode
You could also make those functions friend of your class.

Or make them public? I mean, if you look for a way to read and write the variables without getters/setters, they'll become public anyway, or else you can make only that what's allowed to read/write friend.

Or make something like this?

*** Source Snippet Removed ***


hmm. My concern here is reducing the conceptual overhead. the longer I think about simulating an explosion, the more private members I come up with. Your method in fact has three members for each method. Since the current class, which I will use for testing the principles of the force distribution matrix, has 13 member variables, not to mention the 21 within in the distribution matrix, that means 39 members!

Share this post


Link to post
Share on other sites
Quote:
Original post by Lode

...
Edit: after the other reply from shotgunnutter in the middle it seems that I answered something wrong.

Did you just answer your own question with the part under "instead having something like this"? Give your templated ro's the necessary operator=, operator float(), etc..., and you can get the behaviour you want?


no, I'm considering that, I was asking *if* that would be a good alternative to having getters for each and keeping them private. Just to clarify. This could be another example of shooting oneself in the lower leg.

Share this post


Link to post
Share on other sites
Well, personally I like the approach with the templates, it avoids a lot of code duplication, but maybe that's just me. I think it's maintainable (putting all the logic concerning the read/write stuff in 1 place in the template class), readable, and avoids code duplication so... why not? :)

What you could do extra is put all the roMember<float>'s in a struct ExplosionData and then in your class make 1 getter to get the struct. That is, if you want to avoid having public data members in classes (in a struct that serves only to collect data it's more commonly accepted to have public data).

Share this post


Link to post
Share on other sites
Quote:
Original post by Lode
Well, personally I like the approach with the templates, it avoids a lot of code duplication, but maybe that's just me. I think it's maintainable (putting all the logic concerning the read/write stuff in 1 place in the template class), readable, and avoids code duplication so... why not? :)

What you could do extra is put all the roMember<float>'s in a struct ExplosionData and then in your class make 1 getter to get the struct. That is, if you want to avoid having public data members in classes (in a struct that serves only to collect data it's more commonly accepted to have public data).


OK. Due to this discussion I have decided to try it by the method in my second post. I'll finish the whole thing in a couple of hours and post the implementation back.

Thanks for the advice.

Share this post


Link to post
Share on other sites
I would prefer to implement such classes by (for example) moving explosion's behaviour into the explosion class such that clients do not need to get and set variables but rather ask explosion instances to do things:
class explosion
{
private:
/* stuff */

public:
void update(std::clock_t time_delta);
void affect(thing & thing) const;

};

Σnigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Enigma
I would prefer to implement such classes by (for example) moving explosion's behaviour into the explosion class such that clients do not need to get and set variables but rather ask explosion instances to do things


Quoted for extreme emphasis.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!