Read only access to members

P

pkirk25

Hi all,

Is there an alternative to writing a set/get function for each data
member of a class?

For data members that are never changed once the class is initialised
it would seem logical you could call them read-only in some way.

Thanks in advance.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

pkirk25 said:
Is there an alternative to writing a set/get function for each data
member of a class?

Yes, to write classes that represents objects, not groups of variables. For
example, if you write a Rectangle class, usually makes more sense to
provide member functions to move and change size that to set invidually any
corner, or the width, height and x-y coordinates of a point.
 
V

Victor Bazarov

pkirk25 said:
Is there an alternative to writing a set/get function for each data
member of a class?

Yes. Not writing any.
For data members that are never changed once the class is initialised
it would seem logical you could call them read-only in some way.

Declare them 'const'.

V
 
P

pkirk25

Yes, to write classes that represents objects, not groups of variables. For
example, if you write a Rectangle class, usually makes more sense to
provide member functions to move and change size that to set invidually any
corner, or the width, height and x-y coordinates of a point.

So you would say I am not really doign the data analysis correctly?
Pershaps I could ask your help?

Example:
class bill_of_materials
{
public:
float get_materials_cost();
private:
string item0_name;
int item0_quantity;
float item0_value;
// and so on to item20

}

If my purpose is to be able to access the total value of the materials
easily to compare with the value of the manufactured item, how better
should I structure things?

Thanks in advance.

Patrick
 
V

Victor Bazarov

pkirk25 said:
So you would say I am not really doign the data analysis correctly?
Pershaps I could ask your help?

Example:
class bill_of_materials
{
public:
float get_materials_cost();
private:
string item0_name;
int item0_quantity;
float item0_value;
// and so on to item20

}

If my purpose is to be able to access the total value of the materials
easily to compare with the value of the manufactured item, how better
should I structure things?

It seems that 'bill_of_materials' should rather have a collection of
'material' objects, and each of them should have 'name', 'quantity',
'value' ('price') data members. Something like

class material
{
string name;
float value;
int quantity;
public:
... // some interface to fill those in or query them
};

class bill_of_materials
{
vector<material> materials;
public:
... // interface to add material, query total cost, etc.
};

V
 
C

Cy Edmunds

pkirk25 said:
Hi all,

Is there an alternative to writing a set/get function for each data
member of a class?

For data members that are never changed once the class is initialised
it would seem logical you could call them read-only in some way.

Thanks in advance.

class Point
{
private:
int m_x, m_y;
public:
Point(int i_x, int i_y) : m_x(i_x), m_y(i_y) {}
int x() const {return m_x;} // read-only access
int y() const {return m_y;} // ditto
};

That's pretty minimal but is still a valid object and has no get/set pairs.
You can still change the internal state using the constructor:

Point p(2, 3);
std::cout << p.x() << '\n'; // prints a 2
p = Point(5, 3);
std::cout << p.x() << '\n'; // prints a 5

Syntactically it is not entirely unreasonable to think of Point(5, 3) as a
constant of type Point although that is not really what it is. Anyway I
almost always prefer this paradigm to get/set pairs.

BTW you can even use pointers and still get read only access with the proper
use of const. For instance the class above might have had a function

int const *px() const {return &x;}

which gives you read only access through a pointer (kind of a dumb idea in
this example of course). The first const disables writing to m_x through the
pointer and the second const declares that px does not change the state of
the Point.

Cy
 
H

Howard

Cy Edmunds said:
class Point
{
private:
int m_x, m_y;
public:
Point(int i_x, int i_y) : m_x(i_x), m_y(i_y) {}
int x() const {return m_x;} // read-only access
int y() const {return m_y;} // ditto
};

That's pretty minimal but is still a valid object and has no get/set
pairs.

No "pairs", but it does have "getters". (Which is fine...I'm just
commenting on your statement, not your solution.)
You can still change the internal state using the constructor:

Point p(2, 3);
std::cout << p.x() << '\n'; // prints a 2
p = Point(5, 3);

This does not construct a new p object, if that's what you're implying. It
creates an unnamed temporary using the parameterized constructor, and then
calls the assignment operator to copy the members to p, and then destroys
the temporary. (I forget if the compiler is allowed to somehow optimize
some of that away, however.) (Oh, and it's ok in this case, but would be a
problem if the members were const, or if for some reason the
compiler-generated assignment operator weren't sufficient to the task, such
as if there were pointer members involved.)
std::cout << p.x() << '\n'; // prints a 5

Syntactically it is not entirely unreasonable to think of Point(5, 3) as a
constant of type Point although that is not really what it is. Anyway I
almost always prefer this paradigm to get/set pairs.

What if construction is expensive? (Not that any of this matters here,
since the OP wasn't really interested in changing the values after
construction in the first place.)

Personally, I think Victor's idea of just making the members const it the
easiest and most obvious way.

-Howard
 
C

Cy Edmunds

Howard said:
No "pairs", but it does have "getters". (Which is fine...I'm just
commenting on your statement, not your solution.)

My statement was correct as given. Even if you renamed x() to getx() the
class would have no get/set pairs, which is what I said.
This does not construct a new p object, if that's what you're implying.

I was not implying anything.

It
creates an unnamed temporary using the parameterized constructor, and then
calls the assignment operator to copy the members to p, and then destroys
the temporary.

I know. That's why I said that Point(5, 3) is not really a constant of type
Point.

(I forget if the compiler is allowed to somehow optimize
some of that away, however.)

I would expect any decent compiler to do just that. Try it with your own.

(Oh, and it's ok in this case, but would be a
problem if the members were const, or if for some reason the
compiler-generated assignment operator weren't sufficient to the task,
such as if there were pointer members involved.)

Yeah, if there's no assignment operator you need to do something else. I
generally prefer my classes to have functional assignment operators.
Otherwise they don't work in a lot of contexts.
What if construction is expensive? (Not that any of this matters here,
since the OP wasn't really interested in changing the values after
construction in the first place.)

Personally, I think Victor's idea of just making the members const it the
easiest and most obvious way.

Depends on how you feel about public data members.
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

pkirk25 said:
Hi all,

Is there an alternative to writing a set/get function for each data
member of a class?

For data members that are never changed once the class is initialised
it would seem logical you could call them read-only in some way.

Thanks in advance.

The answers you've already had are pretty good. For your purposes using
const members is probably good.

Here is an alternative that uses templates to deal with accessors:

http://www.kirit.com/C++ killed the get & set accessors


K
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top