Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > const version of a function w/o copy/paste

Reply
Thread Tools

const version of a function w/o copy/paste

 
 
Gernot Frisch
Guest
Posts: n/a
 
      07-22-2010

Hi,

// how can I
const int* GetPInt()const
{
return (const int*)the_non_const_function_using_the_same_name();
}

thank you.
-Gernot

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-22-2010
On 7/22/2010 8:33 AM, Gernot Frisch wrote:
> // how can I
> const int* GetPInt()const
> {
> return (const int*)the_non_const_function_using_the_same_name();
> }


You could do

return const_cast<YourType*>(this)->GetPInt();

but beware of UB. The use of const_cast is only defined *if* you know
for sure that the object is non-const. If you don't, it's UB.

Now, let me ask you, why do you have two versions of the same function?
If they do exactly same thing (and do not change the state of the
object), then drop the non-const one. If they *don't* do the exactly
same thing, then you have no business calling a non-const member from a
const member.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Gernot Frisch
Guest
Posts: n/a
 
      07-22-2010


> Now, let me ask you, why do you have two versions of the same function?


I access members through a pointer. Now, the object can be a const pointer, thus I only get a const pointer to the child and
vice versa:

class child;
class parent
{
child* GetChild() {return &m_child;}
const child* GetChild()const {return &m_child;} // for when parent prt is const
};

thanks for the const cast hint.

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-22-2010
On 7/22/2010 9:26 AM, Gernot Frisch wrote:
>
>
>> Now, let me ask you, why do you have two versions of the same function?

>
> I access members through a pointer.


That's rather odd. Shouldn't it be a reference?

> Now, the object can be a const
> pointer, thus I only get a const pointer to the child and vice versa:
>
> class child;
> class parent
> {
> child* GetChild() {return &m_child;}
> const child* GetChild()const {return &m_child;} // for when parent prt
> is const
> };
>
> thanks for the const cast hint.


It is *better* to have two accessors like you've shown here, than go
through the complexity of "forwarding" from the const accessor to the
non-const one. Cleaner.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-22-2010
On 7/22/2010 9:19 AM, Stuart Golodetz wrote:
> Gernot Frisch wrote:
>>
>> Hi,
>>
>> // how can I
>> const int* GetPInt()const
>> {
>> return (const int*)the_non_const_function_using_the_same_name();
>> }
>>
>> thank you.
>> -Gernot

>
> You should do it the other way round - call the const version from the
> non-const one.[..]


+1

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-22-2010
On Jul 22, 2:12 pm, Victor Bazarov <(E-Mail Removed)> wrote:
> On 7/22/2010 8:33 AM, Gernot Frisch wrote:


> > // how can I
> > const int* GetPInt()const
> > {
> > return (const int*)the_non_const_function_using_the_same_name();
> > }


> You could do


> return const_cast<YourType*>(this)->GetPInt();


> but beware of UB. The use of const_cast is only defined *if*
> you know for sure that the object is non-const. If you don't,
> it's UB.


No. It's only UB if you actually attempt to modify a const
object.

Still, I'd prefer the inverse, calling the const function from
within the non-const one, then casting away const on the results
(since you know that you're not really const there).

> Now, let me ask you, why do you have two versions of the same
> function?


> If they do exactly same thing (and do not change the state of
> the object), then drop the non-const one.


The two functions have different return types. Both in fact do
exactly the same thing, but the return value of one allows
client code to modify the object; the return type of the other
doesn't.

This is a standard idiom for container classes (where GetPInt is
named operator[], and returns a reference rather than a pointer).

--
James
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      07-22-2010
Stuart Golodetz wrote:
> Victor Bazarov wrote:
>> On 7/22/2010 8:33 AM, Gernot Frisch wrote:
>>> // how can I
>>> const int* GetPInt()const
>>> {
>>> return (const int*)the_non_const_function_using_the_same_name();
>>> }

>>
>> You could do
>>
>> return const_cast<YourType*>(this)->GetPInt();
>>
>> but beware of UB. The use of const_cast is only defined *if* you
>> know for sure that the object is non-const. If you don't, it's UB.
>>
>> Now, let me ask you, why do you have two versions of the same
>> function? If they do exactly same thing (and do not change the
>> state of the object), then drop the non-const one. If they
>> *don't* do the exactly same thing, then you have no business
>> calling a non-const member from a const member.
>>
>> V

>
> Presumably the non-const one returns int*, so clients can change
> something in the object through that, but only if the object itself
> is non-const. If the object's const, you want to return a const
> int* to the same thing. Whether or not the class should be exposing
> its internal data like this at all depends on the context I guess.
>
> It's evidently "evil" to call a non-const member from a const one,
> but I was under the impression that there's nothing particularly
> evil about doing it the other way round - in fact, I thought it was
> almost
> idiomatic if you need to provide both a non-const and const
> accessor? It's certainly better than duplicating the code, which is
> the
> alternative...


It surely depends on what the functions do. The one returning an int*
to class member will likely be

int* getbuffer()
{ return &buffer; }

const int* getbuffer() const
{ return &buffer; }


How much duplication can you save here?


Bo Persson



 
Reply With Quote
 
Stuart Redmann
Guest
Posts: n/a
 
      07-23-2010
On 22 Jul., 14:33, "Gernot Frisch" <(E-Mail Removed)> wrote:
> Hi,
>
> // how can I
> const int* GetPInt()const
> {
> * * return (const int*)the_non_const_function_using_the_same_name();
>
> }


We had a similar topic quite recently (http://groups.google.de/group/
comp.lang.c++/browse_frm/thread/7943a399a96324bf#), and came up with
the following class:


// Wrapper for plain pointers that behaves as const-correct
// accessor.
template<class t_Class>
class ConstCorrectAccessor
{
t_Class* m_InternalPointer;
public:
ConstCorrectAccessor (t_Class* Pointer)
: m_InternalPointer (Pointer)
{}


// Accessor methods with const-correct overload.
const t_Class* operator-> () const {return m_InternalPointer;}
t_Class* operator ->() {return m_InternalPointer;}



};


class SomeClass
{
public:
void foo () const {}
void bar () {}


};


class AnotherClass
{
public:
ConstCorrectAccessor<SomeClass> SomeObject;
public:
AnotherClass (SomeClass* Object)
: SomeObject (Object)
{}

void foo () const
{
SomeObject->foo (); // OK
SomeObject->bar (); // Error: Non-const method on SomeObject.
}



};


int main ()
{
SomeClass a;
const AnotherClass b (&a);
b.SomeObject->foo (); // OK
b.SomeObject->bar (); // Compilation error: b is const

AnotherClass c (&a);
c.SomeObject->foo (); // OK
c.SomeObject->bar (); // OK: c is not const



}


Regards,
Stuart
 
Reply With Quote
 
Gernot Frisch
Guest
Posts: n/a
 
      07-26-2010
"Stuart Golodetz" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...


> Yes, unless the accessor does something non-trivial, in which case it's (arguably) better not to duplicate the code (less to
> maintain). As an example I've managed to dig up:
>
> int& SliceLocation:perator[](SliceOrientation ori)
> {
> return const_cast<int&>(const_cast<const SliceLocation*>(this)->operator[](ori));
> }



Excellent. That was exaclty the reason why I asked this question.



 
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
Re: Where to get stand alone Dot Net Framework version 1.1, version2.0, version 3.0, version 3.5, version 2.0 SP1, version 3.0 SP1 ? MowGreen [MVP] ASP .Net 5 02-09-2008 01:55 AM
Re: Where to get stand alone Dot Net Framework version 1.1, version 2.0, version 3.0, version 3.5, version 2.0 SP1, version 3.0 SP1 ? PA Bear [MS MVP] ASP .Net 0 02-05-2008 03:28 AM
Re: Where to get stand alone Dot Net Framework version 1.1, version 2.0, version 3.0, version 3.5, version 2.0 SP1, version 3.0 SP1 ? V Green ASP .Net 0 02-05-2008 02:45 AM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM



Advertisments