C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Public data members

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Dirk Gregorius
Guest





PostPosted: Mon Sep 27, 2004 9:14 pm    Post subject: Public data members Reply with quote



Hi,

I have a class that is a simple wrapper around two STL container.
Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant, so I am wondering if I can make both data
members public and access them directly. You always read that this
break encapsulation, but on the other hand I had to repeat a lot of
functionality. In the calling code I need to to search, sort and
iterate over both containers, so in the above code I need to write
code like GetVectorBegin(), GetMapBegin(), FindInMap() and delegate
everything to the container classes. Since this doesn't raise the
abstraction and since I don't need to defend any invariant I am
wondering if simply defining a struct (s. below) would be the better
choice?

struct
{
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

Questions:
What are the current opinions and recommendations on public data
members - maybe taking into consideration the later use the STL
algorithms?
How should I declare the class interface of the first example in order
to make it STL algorithms compatible?
How about the use of typedefs?

Best regards,

Dirk

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thorsten Ottosen
Guest





PostPosted: Tue Sep 28, 2004 10:20 am    Post subject: Re: Public data members Reply with quote



"Dirk Gregorius" <dirk (AT) dirkgregorius (DOT) de> wrote

Quote:
Hi,

I have a class that is a simple wrapper around two STL container.
Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant, so I am wondering if I can make both data
members public and access them directly.

yes, if there is no invariant then there is nothing for member functions to
protect.

br

Thorsten



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ulrich Eckhardt
Guest





PostPosted: Tue Sep 28, 2004 10:38 am    Post subject: Re: Public data members Reply with quote



Dirk Gregorius wrote:
Quote:
I have a class that is a simple wrapper around two STL container.
Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant, so I am wondering if I can make both data
members public and access them directly. You always read that this
break encapsulation, but on the other hand I had to repeat a lot of
functionality.

I would do it, but with a slight addition: add typedefs for the container
types. Also, I tend to remove the m_ from fublic members, but that is just
a matter of taste.
The point is, as you already figured out, your struct is just like one of
the std::containers - their elements are also unrestrictedly accessible.
Now I think about it, did you consider using std::pair<>? Anyhow, mere
aggregations of data that show no behaviour can usually be left in public.

hth
Uli

--
FAQ: http://parashift.com/c++-faq-lite/
/* bittersweet C++ */
default: break;

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
jakacki
Guest





PostPosted: Tue Sep 28, 2004 10:40 am    Post subject: Re: Public data members Reply with quote

Quote:
I have a class that is a simple wrapper around two STL
container. Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant,

Has trivial invariant ('true').

Quote:
so I am wondering if I can make both data members public
and access them directly. You always read that this break
encapsulation, but on the other hand I had to repeat a
lot of functionality. In the calling code I need to to
search, sort and iterate over both containers, so in the
above code I need to write code like GetVectorBegin(),
GetMapBegin(), FindInMap() and delegate everything to the
container classes. Since this doesn't raise the
abstraction and since I don't need to defend any
invariant I am wondering if simply defining a struct (s.
below) would be the better choice?

If they are really deprived of any domain specific
semantics, why do you keep them together in one
class/structure ?

Quote:
struct
{
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

Questions:

What are the current opinions and recommendations on
public data members - maybe taking into consideration the
later use the STL algorithms?

Encapsulation will allow you at least to optimize the
data structure if, some time later you discover that
80% of map keys are shorter than 3. Also if a lot of
code is going to depend on your interface it is wise to
encapsulate early.

Quote:
How should I declare the class interface of the first
example in order to make it STL algorithms compatible?

What is "STL algorithms compatible" ? Your class looks like
a container, STL algorithms do not work on containers, they
work on iterators. Just have your container provide
STL-compliant iterators.

Quote:
How about the use of typedefs?

What use of typedefs?

BR
Grzegorz

--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Sep 28, 2004 9:23 pm    Post subject: Re: Public data members Reply with quote

[email]dirk (AT) dirkgregorius (DOT) de[/email] (Dirk Gregorius) wrote in message
news:<d5c0fb78.0409271113.3fd36af3 (AT) posting (DOT) google.com>...

Quote:
I have a class that is a simple wrapper around two STL container.
Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant, so I am wondering if I can make both data
members public and access them directly.

I do it. There are still cases where a good old C struct is what is
called for.

Quote:
You always read that this break encapsulation, but on the other hand I
had to repeat a lot of functionality.

The question is: what are you encapsulating. Typically, either all data
members will be private, or all data members will be public, and there
will be no member functions (except maybe some convenience
constructors -- or, in one very special case, a conversion operator).

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dirk Gregorius
Guest





PostPosted: Wed Sep 29, 2004 9:41 am    Post subject: Re: Public data members Reply with quote

Quote:
I would do it, but with a slight addition: add typedefs for the container
types. Also, I tend to remove the m_ from fublic members, but that is just
a matter of taste.
That's what I meant with typedef and I think this is the way I will

go.

Quote:
What is "STL algorithms compatible" ? Your class looks like
a container, STL algorithms do not work on containers, the
work on iterators. Just have your container provide
STL-compliant iterators.
Is there a standard way to do this? This comes to my head:


class Object
{
public:
typedef std::map<std::string, std::string>::iterator MapIterator;
typedef std::vector<int>::iterator VectorIterator;

MapIterator MapBegin( void ); // Delegate to the map
VectorIterator VectorBegin( void ); // Delegate to the vector
// ...

private:
std::map<std::string, std::string> m_Map;
std::vector<int> m_Vector;

};

I need this class to load data from a file. The data is a list of
entities where each entity consists of pairs of strings and optional
some geometric data.
First I implemented a full flavour class whith rich interfaces and
everything possible I could imagine. Then my opinion changed I
implemented a simple function that loads the data simply into a
std::vector<>, which is actually what the file does. Most when not all
of the processing will be standard algortihms, so at the moment I
think that getting rid of all the unneeded indirections is better. On
the other hand I am not the experienced programmer in the world and in
all the books you read always this Dos and Donts and one of them is:
No public data memebers. For this low level objects I though it could
make sense to get rid of the indirections and asked here if this is
possible not a NoNo.

-Dirk

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dave Harris
Guest





PostPosted: Wed Sep 29, 2004 9:58 am    Post subject: Re: Public data members Reply with quote

[email]dirk (AT) dirkgregorius (DOT) de[/email] (Dirk Gregorius) wrote (abridged):
Quote:
This class has no invariant, so I am wondering if I can make both data
members public and access them directly. You always read that this
break encapsulation, but on the other hand I had to repeat a lot of
functionality. In the calling code I need to to search, sort and
iterate over both containers, so in the above code I need to write
code like GetVectorBegin(), GetMapBegin(), FindInMap() and delegate
everything to the container classes.

I hope you could find better names that referred to their domain meaning
rather than their implementation. Eg numbers_begin() is better than
vector_begin(). This isn't just a cosmetic matter. Part of the job of a
class is to manage levels of abstraction.


Quote:
What are the current opinions and recommendations on public data
members - maybe taking into consideration the later use the STL
algorithms?

In practice I find even the simplest classes evolve. I might change from
vector to map or list, or fixed-sized array, or I might need the data to
be sorted, or I might need to allocate it on first use, or whatever. I
also often find that code which uses the data is simpler and shorter if it
lives in the class which defines it. In other words, rather than:

for (Object::Numbers::iterator i = object.m_Numbers.begin();
i != object.m_Numbers.end(); ++i)
use( *i );

I will have:

void Object::use_all_numbers() {
for (Numbers::iterator i = numbers_begin(); i != numbers_end();
++i)
use( *i );
}

Doing this lessens the need to make lower level access public. Life is
even simpler if no class has to work on more than one collection, and it
can be worth making extra classes to achieve this:

void Numbers::use_all() {
for (iterator i = begin(); i != end(); ++i)
use( *i );
}

We no longer have to prefix everything with Object::Numbers::, so now the
loop fits on one 80-column line. This feels better engineered to me, even
if it means writing forwarding functions like:

void Object::use_all_numbers() {
m_numbers.use_all();
}

I don't much use STL algorithms. If I do use them they will probably be
hidden in the implementation of Object, rather than in client code. That
said, I often publish numbers_begin() and numbers_end(), which is all most
STL algorithms need.

The upshot is that I tend to make data private, use typedefs, and write
member functions which often just forward to the container or STL. I have
a lot of classes which have:

class MyContainer {
public:
typedef std::vector<int> Base;
typedef Base::const_iterator const_iterator;
typedef Base::iterator iterator;

bool empty() const;
int size() const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();

private:
Base m_base;
};

inline bool MyContainer::empty() const {
return m_base.empty();
}
// etc

plus other members. On those occasions where I've made variables public
instead, because they were just "dumb data", I've usually ended up
reversing the decision and making the data smarter.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Richard
Guest





PostPosted: Thu Sep 30, 2004 10:46 am    Post subject: Re: Public data members Reply with quote

"jakacki" <jakacki_hates_spam (AT) acm (DOT) org> wrote

Quote:
I have a class that is a simple wrapper around two STL
container. Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant,

Encapsulation will allow you at least to optimize the
data structure if, some time later you discover that
80% of map keys are shorter than 3. Also if a lot of
code is going to depend on your interface it is wise to
encapsulate early.


Why optimize something now that you don't know if you are going to use then.

I would just leave them public. Don't encapsulate for the sake of encapsulation.

/Richard

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Peter Schneider
Guest





PostPosted: Fri Oct 01, 2004 4:13 pm    Post subject: Re: Public data members Reply with quote

Hi,

"Richard" <glanmark (AT) yahoo (DOT) com> wrote

Quote:
"jakacki" <jakacki_hates_spam (AT) acm (DOT) org> wrote

[> > OP Dirk wrote]

Quote:
I have a class that is a simple wrapper around two STL
container. Basically it is something like this:

class Object
{
public:
// Some full flavor interface acually only repeating
// the functionalit of the container classes

private:
std::map<std::string, std::string> m_Dico;
std::vector<int> m_Numbers;
};

This class has no invariant,

Encapsulation will allow you at least to optimize the
data structure if, some time later you discover that
80% of map keys are shorter than 3. Also if a lot of
code is going to depend on your interface it is wise to
encapsulate early.


Why optimize something now that you don't
know if you are going to use then.

But that's the whole point: Encapsulation preserves the
possibility to do yet unknown things
later, for yet unknown reasons,
by yet unknown programmers.

It's an investment. Bad investments can be costly;
missed investments are deadly.

Regards, Peter



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.