By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,146 Members | 1,631 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,146 IT Pros & Developers. It's quick & easy.

overloading based on function being const

P: n/a
The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The non-
const version of display( ) function is provided only for chaining.
The const version of display( ) function is provided to be called on
const Test objects. Given this, I have the following questions:

1)Is it advisable to overload a function like display( ) only on const
(everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object

2) When is overloading a function, only on const inevitable ?

Kindly explain

Thanks
V.Subramanian

Sep 18 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
su**************@yahoo.com wrote:
The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The
non- const version of display( ) function is provided only for
chaining. The const version of display( ) function is provided to be
called on const Test objects. Given this, I have the following
questions:

1)Is it advisable to overload a function like display( ) only on const
(everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object
If they would do exactly the same, and both would not attempt to
modify the object, why have the non-const version AT ALL?
2) When is overloading a function, only on const inevitable ?
When you need different behaviour.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 18 '07 #2

P: n/a
su**************@yahoo.com, India wrote:
The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The non-
const version of display( ) function is provided only for chaining.
The const version of display( ) function is provided to be called on
const Test objects. Given this, I have the following questions:

1)Is it advisable to overload a function like display( ) only on const
(everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object
No need to define a non-const member function if their body are indentical;

It has one case that I can recall, when both member functions are needed

Type const& func() const;
Type & func();

For code reuse, you can write this way:

Type& func()
{
const_cast<Klass*>func(this)->func();
// func() const must return non-const Type object
}
I recalled that this NG or c.l.c++.m has some discussion on this, some
folk even invent some macro to ease this Paired-Member-Function(TM) work.

2) When is overloading a function, only on const inevitable ?
I'm not sure what you mean.

But if I don't get you wrong,
(1) already has your answer.
prefer const member function to non-const one

--
Thanks
Barry

Sep 18 '07 #3

P: n/a
Barry wrote:
[..]
It has one case that I can recall, when both member functions are
needed
Type const& func() const;
Type & func();

For code reuse, you can write this way:

Type& func()
{
const_cast<Klass*>func(this)->func();
// func() const must return non-const Type object
First of all, there has to be a return value. So, following your
pattern it would be

return const_cast<Type&>(const_cast<const Klass*>(this)->func());
// I think you missed the qualifier ^^^^^ here

which is a BAD IDEA(tm) because it promotes undefined behaviour. The
const version of 'func' may return a reference to some truly constant
memory, and the caller may end up wanting to change the return value
somehow: KABOOM!
}
It would be better to duplicate the code to avoid having to deal with
const casts.
I recalled that this NG or c.l.c++.m has some discussion on this, some
folk even invent some macro to ease this Paired-Member-Function(TM)
work. [..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 18 '07 #4

P: n/a
su**************@yahoo.com, India wrote:
The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The non-
const version of display( ) function is provided only for chaining.
The const version of display( ) function is provided to be called on
const Test objects. Given this, I have the following questions:

1)Is it advisable to overload a function like display( ) only on const
(everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object

2) When is overloading a function, only on const inevitable ?
seeing your subject,
it's not overloading, const/non-const members are totally functions
(different signature).

--
Thanks
Barry
Sep 18 '07 #5

P: n/a
Barry wrote:
su**************@yahoo.com, India wrote:
>The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The
non- const version of display( ) function is provided only for
chaining. The const version of display( ) function is provided to be
called on const Test objects. Given this, I have the following
questions: 1)Is it advisable to overload a function like display( ) only
on
const (everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object

2) When is overloading a function, only on const inevitable ?

seeing your subject,
it's not overloading, const/non-const members are totally functions
(different signature).
It's overloading as long as the *name* of the function is the same
and they are both declared in the same *scope*.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 18 '07 #6

P: n/a
Victor Bazarov wrote:
Barry wrote:
>[..]
It has one case that I can recall, when both member functions are
needed
Type const& func() const;
Type & func();

For code reuse, you can write this way:

Type& func()
{
const_cast<Klass*>func(this)->func();
// func() const must return non-const Type object

First of all, there has to be a return value. So, following your
pattern it would be

return const_cast<Type&>(const_cast<const Klass*>(this)->func());
// I think you missed the qualifier ^^^^^ here
Yeh, you are right.
>
which is a BAD IDEA(tm) because it promotes undefined behaviour. The
const version of 'func' may return a reference to some truly constant
memory, and the caller may end up wanting to change the return value
somehow: KABOOM!
I presumed that the returned object is modifiable. when returned by
const member function, it adds constness.

But my intent is actually to show that, we can have different return
type on the Pair-Member-Function.

--
Thanks
Barry
Sep 18 '07 #7

P: n/a
Victor Bazarov wrote:
Barry wrote:
>su**************@yahoo.com, India wrote:
>>The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The
non- const version of display( ) function is provided only for
chaining. The const version of display( ) function is provided to be
called on const Test objects. Given this, I have the following
questions: 1)Is it advisable to overload a function like display( ) only
on
const (everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object

2) When is overloading a function, only on const inevitable ?
seeing your subject,
it's not overloading, const/non-const members are totally functions
(different signature).

It's overloading as long as the *name* of the function is the same
and they are both declared in the same *scope*.
Yeh, you are right.

I has one rule in mind : we can't overloaded a function only by return type.

But the compiler treats const/non-const member functions specially

Type1 A::func(A * this, ...);
Type2 A::func(A const* this, ...);

I did check /overload/'s definition.
When two or more different declarations are specified for a single name
in the same scope, that name is said to be overloaded.

struct A
{
int i;
};

struct B : A
{
int i; // overload if I get the standard right
}

Thanks

--
Thanks
Barry
Sep 18 '07 #8

P: n/a
Barry wrote:
Victor Bazarov wrote:
>Barry wrote:
>>su**************@yahoo.com, India wrote:
The following is a beginner's question.

Suppose TYPE1 and TYPE2 are two types for which suitable ctors and
operator= are defined.

Suppose I have

class Test
{
TYPE1 mem1;
TYPE2 mem2;

public:
Test & member1(const TYPE1 & val1);
Test & member2(const TYPE2 & val2);

Test & display( ) { /* display mem values */ return *this; }

const Test & display( ) const { /* display mem values */ return
*this; }
};

Test & Test::member1(const TYPE1 & val1)
{
mem1 = val1;
return *this;
}

Test & Test::member2(const TYPE2 & val2)
{
mem2 = val2;
return *this;
}

Suppose I define,
TYPE1 val1;
TYPE2 val2;

Test obj;
obj.display( ).member1(val1).member2(val2).display( );

const Test const_obj;
const_obj.display( );

Suppose the body of both the display( ) functions are the same. That
is, display( ) does not modify the data members of the object. The
non- const version of display( ) function is provided only for
chaining. The const version of display( ) function is provided to be
called on const Test objects. Given this, I have the following
questions: 1)Is it advisable to overload a function like display( )
only on
const (everything else being the same for this function) for chaining
purpose when it does not modify the data members of the object

2) When is overloading a function, only on const inevitable ?

seeing your subject,
it's not overloading, const/non-const members are totally functions
(different signature).

It's overloading as long as the *name* of the function is the same
and they are both declared in the same *scope*.

Yeh, you are right.

I has one rule in mind : we can't overloaded a function only by return
type.

But the compiler treats const/non-const member functions specially

Type1 A::func(A * this, ...);
Type2 A::func(A const* this, ...);

I did check /overload/'s definition.
When two or more different declarations are specified for a single name
in the same scope, that name is said to be overloaded.

struct A
{
int i;
};

struct B : A
{
int i; // overload if I get the standard right
Sorry, again, not the same *scope*
}


--
Thanks
Barry
Sep 18 '07 #9

P: n/a
On Sep 18, 6:02 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
2) When is overloading a function, only on const inevitable ?

When you need different behaviour.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Kindly explain what is meant by behaviour of a function ? Does it mean
the task performed by a function - say for example finding the square
root of a function ?

Kindly give the body of a function explaining what is meant by
behaviour of a function.

Thanks
V.Subramanian

Sep 19 '07 #10

P: n/a
su**************@yahoo.com, India wrote:
On Sep 18, 6:02 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>>2) When is overloading a function, only on const inevitable ?

Kindly explain what is meant by behaviour of a function ? Does it mean
the task performed by a function - say for example finding the square
root of a function ?
One typical example of a non-const and a const member function doing a
"different" thing is the begin() member function of STL containers: If
you call the non-const version it will return an 'iterator' (which
allows you modifying the element pointed by the iterator) but if you
call the const version it will return a 'const_iterator' (which will not
allow modification).

The implementations of these two functions are basically different:
They instantiate and return completely different classes.
Sep 19 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.