set/get in c++.

M

Manzanita

Hi.

In order to reduce the size of my headers and join definitions of
variables and definitions of inline functions, i use a macro i saw in
this group for all built-in types and types with assignment operator.


#define ATRIBUTO( type, x) \
private: \
type x; \
public: \
type & Get##x() { return x; } \
type Get##x() { return x; } const \
void Set##x( type value ) { x = value; } \

class A{
ATRIBUTO(char, caracter);
};


1.- Can be flawed this macro?.

2.- Is there any workaround so that the names of the functions are
expanded to a name with the first letter following Set or Get capital?, i
mean:
GetCaracter and SetCaracter instead of Getcarater and Setcaracter.

I want to use caracter rather than Caracter inside the member
functions of A.

Thank you in advance and excuse my bad english.
 
K

Kevin Goodsell

Manzanita said:
Hi.

In order to reduce the size of my headers and join definitions of
variables and definitions of inline functions, i use a macro i saw in
this group for all built-in types and types with assignment operator.


#define ATRIBUTO( type, x) \
private: \
type x; \
public: \
type & Get##x() { return x; } \
type Get##x() { return x; } const \
void Set##x( type value ) { x = value; } \

class A{
ATRIBUTO(char, caracter);
};

This is officially one of the worst ideas I've ever seen posted on this
group.

-Kevin
 
J

John Harrison

Manzanita said:
Hi.

In order to reduce the size of my headers and join definitions of
variables and definitions of inline functions, i use a macro i saw in
this group for all built-in types and types with assignment operator.


#define ATRIBUTO( type, x) \
private: \
type x; \
public: \
type & Get##x() { return x; } \
type Get##x() { return x; } const \
void Set##x( type value ) { x = value; } \

class A{
ATRIBUTO(char, caracter);
};


1.- Can be flawed this macro?.

This is better.

class A
{
public:
char character;
};

but this is very bad and your version is very, very bad. I think you need to
do some revision in object oriented design.

john
 
P

Pete Vidler

John Harrison wrote:
[snip]
but this is very bad and your version is very, very bad. I think you need to
do some revision in object oriented design.
[snip]

I agree that his macro was ugly (and bad code), but I'm not sure there's
anything intrinsically wrong with get/set methods. I often find them
quite useful.

The problem comes when the get/set methods are tied to implementation
details on a one-to-one basis (like in the macro).

-- Pete
 
K

Kevin Goodsell

Pete said:
John Harrison wrote:
[snip]
but this is very bad and your version is very, very bad. I think you
need to
do some revision in object oriented design.

[snip]

I agree that his macro was ugly (and bad code), but I'm not sure there's
anything intrinsically wrong with get/set methods. I often find them
quite useful.

The problem comes when the get/set methods are tied to implementation
details on a one-to-one basis (like in the macro).

When it's done as a matter of policy, yes. It's possible a straight
1-to-1 mapping would be perfectly good in some cases, but it shouldn't
be assumed that this is the "right way" to create a class. Such cases
are, in my experience, quite rare.

A few problems that come to mind with the given macros:

1) Class invariants (if any) cannot be maintained, unless you code those
functions that need to be concerned with this separately. It's also too
easy to simply forget invariant assurance.

2) Encourages sloppy and lazy design.

3) It's a macro, so it has all the problems macros have (no scoping
rules, not subject to various other language rules, confusing to debug,
etc.)

4) Very limited flexibility. What if I want an array member? I'd have
use a typedef to alias the type name first, and the get/set methods
would have unexpected semantics (pointers, not arrays) in that case.

5) Changing the design is impractical without rewriting the entire class
(though in this case rewriting would be a Good Thing).

In my experience with C++, the need for cookie-cutter get and set
methods has never been prevalent enough for me to consider resorting to
this or any other way of automatically generating them. I think only a
newbie, doing typical over-simplistic and repetitive newbie projects,
would be tempted by such a thing.

Kevin
 
T

Thomas Matthews

Manzanita said:
Hi.

In order to reduce the size of my headers and join definitions of
variables and definitions of inline functions, i use a macro i saw in
this group for all built-in types and types with assignment operator.
[snip]

If you don't like typing your code then create a tool that will
do all that for you. That is what I did. When I answer just a
few questions, the tool sets up the header and source files for
me. It was worth the investment.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
S

Siemel Naran

Kevin Goodsell said:
Manzanita wrote:

In providing get and set functions, there is almost no encapsulation of
member 'x'. However, this may be OK sometimes.
This is officially one of the worst ideas I've ever seen posted on this
group.

I think we could use recursive derivation templates.

template <class MoreDerived, class T, int indx=0>
class Attributo {
public:
typedef Attributo<MoreDerived, T>
Attributo() : d_value() { }
const T& get() { return d_value; }
void set(const T& value) { d_value = value; }
private:
T d_value;
};

class MyClass : public Attributo<MyClass, int>, public Attributo<MyClass,
double> {
public:
typedef Attributo<MyClass, int> Int;
typedef Attributo<MyClass, double> Double;
virtual ~MyClass();
};

int main() {
MyClass mc;
mc.Int::set(3);
mc.Double::set(5.0);
}

I don't like the part where we typedef the base class to Int as we duplicate
the <MyClass, int> part. It would be nice if we could alias the base
classes as in SQL.

select last_name, count(*) as count_last_name
from contacts
group by last_name
having count_last_name>1

class MyClass : public Attributo<MyClass, int> Int, public
Attributo<MyClass, double> Double {
 
M

Manzanita

A few problems that come to mind with the given macros:

1) Class invariants (if any) cannot be maintained, unless you code
those functions that need to be concerned with this separately. It's
also too easy to simply forget invariant assurance.

2) Encourages sloppy and lazy design.

The other way around, i don't feel like typing three times lines when i
could type just one.
3) It's a macro, so it has all the problems macros have (no scoping
rules, not subject to various other language rules, confusing to
debug, etc.)

#ifndef SOME_MACRO
#define SOME_MACRO
#endif
class A{
//uses SOME_MACRO
};
#undef SOME_MACRO

And some compilers are able to expand the macros in the debug phase.
4) Very limited flexibility. What if I want an array member? I'd have
use a typedef to alias the type name first, and the get/set methods
would have unexpected semantics (pointers, not arrays) in that case.

An array is never a pointer, the compiler simply evaluates the name of an
array to the address of the first element except inside the sizeof
operator and in the initialization of non-const references. Please, read
the FAQ before posting.

I don't remember having said nothing about array members, but it would be
easy to define a macro that would work for array members. Anyway if i had
to define lots of (say) strings, i'd prefer:

class A{
public:
enum index {Energy, Mass, Load, Total = Load};
void SetString(string aString, index aIndex){Strings[aIndex] =
aString;}
std::string & GetString(index aIndex){return Strings[aIndex];}
const std::strign GetString(index aIndex){return Strings[aIndex];}
const;
private:
std::string Strings[Total];
};

This way, i wouldn't have to type that much.
5) Changing the design is impractical without rewriting the entire
class (though in this case rewriting would be a Good Thing).

Precisely this macro makes sense for me in the beggining of coding, when
one is writing the class, later you can get rid of it, Thomas Matthews
gave a good idea.

--
 
K

Kevin Goodsell

Manzanita said:
The other way around, i don't feel like typing three times lines when i
could type just one.

Good for you.
#ifndef SOME_MACRO
#define SOME_MACRO
#endif
class A{
//uses SOME_MACRO
};
#undef SOME_MACRO

And some compilers are able to expand the macros in the debug phase.

None of this solves all the problems, and you've made your code uglier.
An array is never a pointer, the compiler simply evaluates the name of an
array to the address of the first element except inside the sizeof
operator and in the initialization of non-const references. Please, read
the FAQ before posting.

You missed as the operand of the address-of operator. But where exactly
did I claim that an array is a pointer? Oh, that's right, I didn't.
Maybe you should re-read what I wrote and think about it a little.

I've participated in this group for years and have several hundred
posts. I've contributed to the FAQ. You're the newbie here, not me.
I don't remember having said nothing about array members, but it would be
easy to define a macro that would work for array members. Anyway if i had
to define lots of (say) strings, i'd prefer:

class A{
public:
enum index {Energy, Mass, Load, Total = Load};
void SetString(string aString, index aIndex){Strings[aIndex] =
aString;}
std::string & GetString(index aIndex){return Strings[aIndex];}
const std::strign GetString(index aIndex){return Strings[aIndex];}
const;
private:
std::string Strings[Total];
};

This way, i wouldn't have to type that much.

Yay?

I know another way to save typing. It goes like this: Don't post inane
messages defending lame ideas on Usenet groups. You should try it sometime.

I mean, if you're *that* concerned with avoiding typing...
Precisely this macro makes sense for me in the beggining of coding, when
one is writing the class, later you can get rid of it, Thomas Matthews
gave a good idea.

I'd prefer to get rid of it at the beginning.

-Kevin
 
M

Manzanita

[...]
You missed as the operand of the address-of operator. But where
exactly did I claim that an array is a pointer? Oh, that's right, I
didn't. Maybe you should re-read what I wrote and think about it a
little.

You're utterly right here, i'm sorry.
I've participated in this group for years and have several hundred
posts. I've contributed to the FAQ. You're the newbie here, not me.

This is the third time i see the word "newbie" in your posts. Don't
expect insults or offences from me.

[...]
Yay?

I know another way to save typing. It goes like this: Don't post inane
messages defending lame ideas on Usenet groups. You should try it
sometime.

I mean, if you're *that* concerned with avoiding typing...

Although my question was easy for you, it doesn't mean it was off-topic.
Anyway, i'm in my twenties and i know to decide by myself. You order me
to shut up my lame ideas just becouse they are easy for you, i'd only
dare to suggest you to read -if you haven't- "Dialogs", from Platon and
later examine this sentence:

<quoute>

"This is officially one of the worst ideas I've ever seen posted on this
group."

<end of quote and of post>

I spent much time with childs with Down's sindrome, and reasoning was far
more important than showing knowledge in a total and humiliating way.

This is my last post here, but sincerely, thanks for your time and the
time of the posters, now i know that i was wrong and that encapsulation
is a key idea. Providing get/set functions is just a way to make data
public which must be examined carefully and using macros even worsen
things for their inherent properties.
 
K

Kevin Goodsell

Manzanita said:
Although my question was easy for you, it doesn't mean it was off-topic.
Anyway, i'm in my twenties and i know to decide by myself. You order me
to shut up my lame ideas just becouse they are easy for you,

Actually, I didn't say it was off-topic or order you to shut up. I just
suggested that you could save a lot of typing by not debating it. Which
is of course true, but the point is that avoiding typing should not be a
primary consideration when coding.
i'd only
dare to suggest you to read -if you haven't- "Dialogs", from Platon and
later examine this sentence:

<quoute>

"This is officially one of the worst ideas I've ever seen posted on this
group."

<end of quote and of post>

I spent much time with childs with Down's sindrome, and reasoning was far
more important than showing knowledge in a total and humiliating way.

You did say this wasn't your idea. And in fact I remember when it came
up before (quite a long time ago, as I recall, though perhaps that
wasn't the only occasion). So this probably shouldn't be taken as an
attack on you. I just think it's a very bad idea, and you probably
shouldn't use it.

For the record, while my initial reply was blunt, my confrontational
reply only came after (what I interpreted as) a similarly
confrontational message from you. Perhaps I misinterpreted the tone of
that message, in which case I owe you an apology.

-Kevin
 

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

Forum statistics

Threads
473,775
Messages
2,569,601
Members
45,182
Latest member
alexanderrm

Latest Threads

Top