Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Const/non-const pointer returning method

Reply
Thread Tools

Const/non-const pointer returning method

 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      05-25-2010
Hi,

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; }
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';
}

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. 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)? 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?

Best regards, Jens
--
\ Jens Thoms Toerring ___
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      05-25-2010
Jens Thoms Toerring wrote:

> Hi,
>
> 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; }
> 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.

> 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.

> 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?


> 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.


Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
 
Salt_Peter
Guest
Posts: n/a
 
      05-25-2010
On May 25, 2:03*pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> Hi,
>
> * 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; }
> * * 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';
>
> }
>
> 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. 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)? 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?
>
> * * * * * * * * * * * * * * Best regards, Jens
> --
> * \ * Jens Thoms Toerring *___ * * *j...@toerring.de
> * *\__________________________ * * *http://toerring.de


first off, the following is not a const ptr:
int const * p; // mutable pointer to a constant
but this is a const ptr to a mutable integer:
int * const p

in C++, one would instead use a std::vector with [] or at(), in the
case you really do prefer a primitive array, use a template.

template< typename T, std::size_t SIZE >
class A

T m_t[ SIZE ];
public:
A() { } // def ctor required for type T
T& operator[](const std::size_t i) { return m_t[i]; }
};

Automatic allocation is safer, easier and preferred. Only new when you
absolutely must.

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      05-25-2010
* Jens Thoms Toerring, on 25.05.2010 20:03:
>
> 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; }
> 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';
> }


Do you?


<example>
C:\test> gnuc x.cpp
x.cpp:8: error: 'int* A::ip() const' cannot be overloaded
x.cpp:7: error: with 'const int* A::ip() const'

C:\test> msvc x.cpp
x.cpp
x.cpp( : error C2556: 'int *A::ip(void) const' : overloaded function differs
only by return type from 'const int *A::i
p(void) const'
x.cpp(7) : see declaration of 'A::ip'
x.cpp( : error C2373: 'A::ip' : redefinition; different type modifiers
x.cpp(7) : see declaration of 'A::ip'
x.cpp( : error C2143: syntax error : missing ';' before '<<'
x.cpp( : warning C4517: access-declarations are deprecated; member
using-declarations provide a better alternative
x.cpp( : error C2886: 'std::cerr' : symbol cannot be used in a member
using-declaration
C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\iostream(14) : see declaration of 'std::cerr'
x.cpp( : error C2238: unexpected token(s) preceding ';'
x.cpp( : error C2059: syntax error : 'return'
x.cpp( : error C2238: unexpected token(s) preceding ';'
x.cpp(10) : error C2143: syntax error : missing ';' before ':'
x.cpp(10) : error C2059: syntax error : ':'
x.cpp(12) : error C2059: syntax error : '}'
x.cpp(12) : error C2143: syntax error : missing ';' before '}'
x.cpp(12) : error C2059: syntax error : '}'
x.cpp(17) : error C2264: 'A::ip' : error in function definition or declaration;
function not called

C:\test> _
</example>



> 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.


I rather doubt it.

First your program needs to compile.


> 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)? 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?


As a first step, get your program to compile.

You can safely disregard the earlier comments in this thread until your code
compiles.

And then it may turn out that the code that compiles is not what those comments
are about.


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
Saeed Amrollahi
Guest
Posts: n/a
 
      05-25-2010
On May 25, 10:03*pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> Hi,
>
> * 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; }
> * * 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';
>
> }
>
> 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. 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)? 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?
>
> * * * * * * * * * * * * * * Best regards, Jens
> --
> * \ * Jens Thoms Toerring *___ * * *j...@toerring.de
> * *\__________________________ * * *http://toerring.de


Hi Jens

At first your code doesn't work. You can't overload
a function just base on different return type.
I guess your ip member functions should be like this:
int const * ip( ) const { std::cout << "const\n"; return m_ip; }
int * ip( ) { std::cerr << "non-const\n"; return m_ip; }
Second, if you allocate memory in construtor,
you must free it in destructor:
A( int i ) : m_ip( new int[i]) { } // new an array
~A() { delete [] ip; } // delete the array
Third, You didn't initialize your array. Constructor
is the best way for initialization. For example:
A( int i ) : m_ip( new int[ i ] )
{
std::fill(m_ip, m_ip + i, 0);
}
about your question:
the const member function means
1. You don't want to change the state of object via it
2. For const object, just const member function should be called.
It is the obvious result of #1

See the following code:
A a( 10 );
int const * ip = a.ip();
ip[0]++; // error *ip is const;
int* ip2 = a.ip();
ip2[1]++; // OK: *ip2 is not const
const A a2(20);
a2.ip(); // calling const ip

Regards,
-- Saeed Amrollahi
 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      05-25-2010
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
 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      05-25-2010
Saeed Amrollahi <> wrote:
> On May 25, 10:03Â*pm, j...@toerring.de (Jens Thoms Toerring) wrote:
> > Hi,
> >
> > Â* 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; }
> > Â* Â* 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';
> >
> > }
> >
> > 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. 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)? 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?
> >
> > Â* Â* Â* Â* Â* Â* Â* Â* Â* Â* Â* Â* Â* Â* Best regards, Jens
> > --
> > Â* \ Â* Jens Thoms Toerring Â*___ Â* Â* Â*j...@toerring.de
> > Â* Â*\__________________________ Â* Â* Â*http://toerring.de


> Hi Jens


> At first your code doesn't work. You can't overload
> a function just base on different return type.
> I guess your ip member functions should be like this:
> int const * ip( ) const { std::cout << "const\n"; return m_ip; }
> int * ip( ) { std::cerr << "non-const\n"; return m_ip; }


Yes, exactly - obviously a gone-wrong last minute change
before pasting it into my post. Won't happen again if I
can avoid it.

> Second, if you allocate memory in construtor,
> you must free it in destructor:
> A( int i ) : m_ip( new int[i]) { } // new an array
> ~A() { delete [] ip; } // delete the array
> Third, You didn't initialize your array. Constructor
> is the best way for initialization. For example:
> A( int i ) : m_ip( new int[ i ] )
> {
> std::fill(m_ip, m_ip + i, 0);
> }


Yes, had snipped all that parts since I wanted to example
as short as possible.

> about your question:
> the const member function means
> 1. You don't want to change the state of object via it
> 2. For const object, just const member function should be called.
> It is the obvious result of #1


I hadn't been aware that the const-returning function would
only be invoked for a const object but laboured under the
wrong impression that what I assign it to would make a dif-
ference. I hope I will keep that in mind in the future

> See the following code:
> A a( 10 );
> int const * ip = a.ip();
> ip[0]++; // error *ip is const;
> int* ip2 = a.ip();
> ip2[1]++; // OK: *ip2 is not const
> const A a2(20);
> a2.ip(); // calling const ip


Yes, I see.
Thanks and best regards, Jens

--
\ Jens Thoms Toerring ___
\__________________________ http://toerring.de
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      05-25-2010
Jens Thoms Toerring wrote:

> 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';
>> > }


[...]
>> > 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 see: you want copy-on-write. The problem is _where_ and _how_ the copy-on-
write should be handled. It is somewhat tricky to use COW with classes that
have not been designed with that in mind. Your options include:

a) If you control the classes that your container should contain, then have
them handle the COW transparently and just use std::vector (or some other
container type from STL) as the container. The copy will be made
transparently when a non-const member function on the retreived object is
invoked.

b) Change the interface of the container so that you don't rely on
"overloading via return type". E.g.: have different names for functions
returning const references or do something like:

void get_ptr ( T const * & p_ref, size_type index );
void get_ptr ( T * & p_ref, size_type index );


Best

Kai-Uwe Bux

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-25-2010
On May 25, 9:10 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Jens Thoms Toerring wrote:
> > Kai-Uwe Bux <jkherci...@gmx.net> 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';
> >> > }


> [...]


> >> > 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();


That's awkward. And if the goal is to have different behavior
depending on what the client code does with the results, it's
very error prone, even supposing you control all of the client
code.

> >> 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 see: you want copy-on-write. The problem is _where_ and
> _how_ the copy-on- write should be handled. It is somewhat
> tricky to use COW with classes that have not been designed
> with that in mind. Your options include:


> a) If you control the classes that your container should
> contain, then have them handle the COW transparently and just
> use std::vector (or some other container type from STL) as the
> container. The copy will be made transparently when a
> non-const member function on the retreived object is invoked.


> b) Change the interface of the container so that you don't
> rely on "overloading via return type". E.g.: have different
> names for functions returning const references or do something
> like:


> void get_ptr ( T const * & p_ref, size_type index );
> void get_ptr ( T * & p_ref, size_type index );


The usual solution in such cases is to return a proxy class, so
that you can effectively overload on what the client code does
with the object.

--
James Kanze
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      05-25-2010
James Kanze wrote:

> On May 25, 9:10 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> Jens Thoms Toerring wrote:
>> > Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> >> Jens Thoms Toerring wrote:

[...]
>> > 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 see: you want copy-on-write. The problem is _where_ and
>> _how_ the copy-on- write should be handled. It is somewhat
>> tricky to use COW with classes that have not been designed
>> with that in mind. Your options include:

>
>> a) If you control the classes that your container should
>> contain, then have them handle the COW transparently and just
>> use std::vector (or some other container type from STL) as the
>> container. The copy will be made transparently when a
>> non-const member function on the retreived object is invoked.

>
>> b) Change the interface of the container so that you don't
>> rely on "overloading via return type". E.g.: have different
>> names for functions returning const references or do something
>> like:

>
>> void get_ptr ( T const * & p_ref, size_type index );
>> void get_ptr ( T * & p_ref, size_type index );

>
> The usual solution in such cases is to return a proxy class, so
> that you can effectively overload on what the client code does
> with the object.


In my experience, that proxy class tends to grow over time and in the end it
forwards all member functions of the underlying class to make informed and
well-suited decisions on whether to copy or not. Effectively, one writes a
wrapper that essentially reproduces option (a).

Of course, if we could overload the dot-operator ... <g>


However, you are correct: I missed that option, which I should have
mentioned.


Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointer to an array vs pointer to pointer subramanian100in@yahoo.com, India C Programming 5 09-23-2011 10:28 AM
Pointer to pointer or reference to pointer A C++ 7 07-05-2011 07:49 PM
Pointer to pointer Vs References to Pointer bansalvikrant@gmail.com C++ 4 07-02-2009 10:20 AM
passing the address of a pointer to a func that doesnt recieve a pointer-to-a-pointer jimjim C Programming 16 03-27-2006 11:03 PM
Pointer-to-pointer-to-pointer question masood.iqbal@lycos.com C Programming 10 02-04-2005 02:57 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57