Kai-Uwe Bux <> wrote:
> Jens Thoms Toerring wrote:
> > I am rather new to C++ and have run into a problem where I
> > haven't found an answer yet by searching (probably didn't find
> > the right search terms). I Have this simple program:
> >
> > #include <iostream>
> >
> > class A
> > {
> > public:
> > A( int i ) : m_ip( new int[ i ] ) { }
> > int const * ip( ) const { std::cout << "const\n"; return m_ip; }
^^^^^
Sorry, that was a mistake just before copy-and-paste...
> > int * ip( ) const { std::cerr << "non-const\n"; return m_ip; }
> >
> > private:
> > int * m_ip;
> > };
> >
> > int main( )
> > {
> > A a( 10 );
> > int const * ip = a.ip( );
> > std::cout << ip[ 2 ] << '\n';
> > }
> Remark: as an illustration for the problem of which member function is
> called, the code is fine. Considered on its own, however, class A leaves
> room for improvement, e.g., with regard to memory management and
> encapsulation.
Yes, of course, this wasn't meant to be production quality code
but just a bare-bones example, so it leaks memory etc.
> > My exectation was that when calling ip() to get a const pointer
> > the compiler would be able to figure out I want it to use the
> > first ip() method that returns a const pointer. But it turns out
> > that always the second one is invoked.
> You will have to adjust your expectations (if you have not already done so).
> The object a was not declared const. Hence any method call a.method() will
> always invoke the non-const version.
Well, I am in the process of adjusting my expectations all the
time

That's part of the fun of learning a new language...
> > I'm not sure why and if
> > there's a way that I can make it pick the second one (short of
> > using different names for the methods)?
> Yes, you could do:
> A a ( 10 );
> A const & b ( a ); // be is a const alias for the object a.
> int const * ip = b.ip();
> Alternatively, some trickery using casts would do.
> BTW: why would you want the const method invoked?
That's a bit longer story: The array in the class will be an
array of pointers to rather large amounts of data. And I will
need lots of copies of that class. In the copies typically
only small subsets of the data will have to be changed. Thus,
to keep the total amount of memory used down, my idea was to
have boost::shared_ptr's in the array (thus having a refe-
rence count and automatic deallocation) and to make a "real"
copy of an element only when it is needed, i.e. when a non-
const instance of the element is requested and the reference
count isn't 1. For that I had hoped for the function for re-
turning a const reference/pointer to be invoked when a const
reference/pointer is requested and the non-const returning
version otherwise (in which then a copy is made when neces-
sary). And then, of course, I hoped to make all that com-
pletely transparent to the user of the class, so they don't
have to think too much about what they're doing...
> > I also noticed the same
> > effect when using const versus non-const references as return
> > values, also there the non-const returning function is called
> > eben when one asks for a const reference. Does all this only
> > work when overloading the [] operator?
> The operator[] is not different: the const version is called on const
> objects and the non-const version is called on non-const objects. So it is
> not clear, what you observed.
Probably my observations weren't very good. to be honest at
the moment I'm still a bit overloaded with understanding
what is happening when

But your explanation has hopefully
cleared up a few misconceptions.
Best regards, Jens
--
\ Jens Thoms Toerring ___
\__________________________
http://toerring.de