Re: design dilemma

From: Arkadiy Vertleyb (vertleyb_at_hotmail.com)
Date: 03/07/04


Date: 7 Mar 2004 05:21:58 -0800


"Daniel T." <postmaster@eathlink.net> wrote

> One of the basic rules of OO is that clients should not be allowed to
> change the state of an object except by directly calling a member
> function of the object. So for example:
>
> class Foo {
> int my_state;
> public:
> int* getState() const { return &my_state; }
> };
>
> is bad because a client can do this:
>
> int* its_state = my_foo.getState();
>
> That int* could then get passed to any number of functions, none of
> which have any obvious connection to Foo. These functions could change
> the Foo objects state in non-obvious ways.
>
> One of the ways to guard against this kind of abuse in C++ is ensure the
> state variable is exposed only through a const object...
>
> const int* Foo::getState() const { return &my_state; }

In your example I would just return by value... However, if you
return a pointer (or iterator) to another object, sometimes it is
useful to define both functions, like in STL:

const_iterator begin() const;
iterator begin();

So, when you call begin on a const container you get a const iterator,
and can not modify items of this container. And visa-versa for
non-const containers. The whole thing needed for handling objects of
technically different, but related classes.

Of course, depending on the context, we can ommit non-const version,
as in your example.

> Now, clients cannot play with the state of our Foo object indirectly. Of
> course there are still some nasty lifetime issues here, and Foo's state
> is no longer properly encapsulated (my_state is no longer an aggregate,
> instead it becomes a simple association) which seems rather odd if this
> variable really is part of Foo's intrinsic state.
>
> I tend to make the whole issue moot by turning my 'getters' into factory
> functions. That way, I can maintain full control over the lifetime of my
> state objects, and I don't have to worry about outsiders playing with my
> state indirectly. Switching to a const reference then becomes a
> performance issue...

I think the original question was about how to allow just one other
class to access a private member variable. This is what C++ friends
are for. So, as I said, I would just have a private member variable,
and declare another class (or just one function in this class) a
friend of the class with this member variable.

Creating a factory for this particular issue looks like overdesign to
me :)

Regards,
Arkadiy



Relevant Pages

  • Re: typedef, member function and const meat different compilers
    ... F const equals const F, so g++ should complain on both. ... > typedef const F H; ... but const-qualifying a function pointer does. ... I and J are member pointers, but there is no type int. ...
    (comp.lang.cpp)
  • Re: Simple question on Pointers
    ... Such a member is, of course, bad idea. ... declared as const SomeClass, this method exhibits undefined ... The code declares no such thing. ...
    (microsoft.public.vc.language)
  • Re: Simple question on Pointers
    ... Such a member is, of course, bad idea. ... const SomeClass, this method exhibits undefined behavior, but you won't ... your completely unambiguous declaration that m_iMember is, in fact, constant ...
    (microsoft.public.vc.language)
  • Re: Getting non "const" pointers to object data using "const" members
    ... My object is actually a tree container, ... safety or const correctness. ... Make this a private nested class of the tree container. ... I use a polymorphic member actually truely named "visit", which is a "const" member implemented either for getting the pointer in the node itself or in another class which is a sub-container for several nodes or nodes containers. ...
    (microsoft.public.vc.language)
  • Re: Simple question on Pointers
    ... SomeClass* global = NULL; ... member function can be called on an object-expression only if the object-expression is as cv-qualified or less-cv-qualified than the member function.". ... It implies that "this" parameter of Memberpoints to a non-volatile object, but it can point to a const object, as well as ... Nobody expects that the standard will introduce undefined behavior, and after all it will define it or "say something about". ...
    (microsoft.public.vc.language)