Hi,
Could someone explain the reasoning behind why the following code is
invalid?
class child
{
public:
void constmethod() const {}
void nonconstmethod() {}
};
class parent
{
public:
const child& mychild() const {return m_child;}
private:
child& mychild() {return m_child;}
child m_child;
};
int main(int argc, char* argv[])
{
parent p;
p.mychild().constmethod();
return 0;
}
I understand that p is a non-const instance of parent but I don't
understand why the compiler can't just resolve the mychild call to the
public const version of the method instead of complaining it can't
access the private version.
I'm sure there's a very good reason for this, I just can't see it!
David
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
davidagal
|
11/2/2004 8:52:42 PM |
|
David Gal wrote:
>
> I understand that p is a non-const instance of parent but I don't
> understand why the compiler can't just resolve the mychild call to the
> public const version of the method instead of complaining it can't
> access the private version.
>
> I'm sure there's a very good reason for this, I just can't see it!
>
For overload resolution purposes, the nonconst mychild() is a better
match than the const overload. In standardese it's called the "best
viable function". Access specifiers are only applied after the best
viable function has been selected. In the standard (�13.3/5):
"If a best viable function exists and is unique, overload resolution
succeeds and produces it as the result. Otherwise overload resolution
fails and the invocation is ill-formed. When overload resolution
succeeds, and the best viable function is not accessible (clause 11) in
the context in which it is used, the program is ill-formed."
and clause 11 paragraph 4 is even more explicit:
"It should be noted that it is access to members and base classes that
is controlled, not their visibility. Names of members are still visible,
and implicit conversions to base classes are still considered, when
those members and base classes are inaccessible. The interpretation of a
given construct is established without regard to access control. If the
interpretation established makes use of inaccessible member names or
base classes, the construct is ill-formed."
IMHO, the key point is in the sentence "The interpretation of a given
construct is established without regard to access control."
Regards,
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Alberto
|
11/3/2004 9:57:34 AM
|
|
David Gal wrote:
> Could someone explain the reasoning behind why the following code is
> invalid?
>
> class child
> {
> public:
> void constmethod() const {}
> void nonconstmethod() {}
> };
>
> class parent
> {
> public:
> const child& mychild() const {return m_child;}
>
> private:
> child& mychild() {return m_child;}
>
> child m_child;
> };
>
> int main(int argc, char* argv[])
> {
> parent p;
> p.mychild().constmethod();
> return 0;
> }
>
> I understand that p is a non-const instance of parent but I don't
> understand why the compiler can't just resolve the mychild call to the
> public const version of the method instead of complaining it can't
> access the private version.
>
> I'm sure there's a very good reason for this, I just can't see it!
Name resolution is done before checking access rights. That's just how
things are. The resolution finds that there are two members 'mychild'.
It sees that the object is non-const. It picks the non-const variation
of 'mychild'. That's the extend of _name_resolution_. Then it verifies
the access rights. Finds a violation. A simple two-stage process that
is _always_ the same. Access specifiers have _no_ bearing on resolution
of the names.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Victor
|
11/3/2004 9:58:35 AM
|
|
This is covered extensively in "Exceptional C++ Style" by Herb Sutter.
Put simply, when selecting which method to call, the compiler does the
following three things, in this order:
1] find the first scope that contains at least one function of the
correct name
2] from this set of functions, select the single best overload
3] check access rights
joshua lehrer
factset research systems
NYSE:FDS
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
usenet_cpp
|
11/4/2004 11:53:07 AM
|
|
Regardless of the accessibility of the function, your private
mychild() is a candidate in overload resolution. Since it is the best
match, that function gets selected. Since it is private method you get
that error.
--lsu
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
suresh
|
11/4/2004 12:01:30 PM
|
|
davidagal@gmail.com (David Gal) wrote in message news:<9e6d76f6.0411020610.18120faf@posting.google.com>...
> Hi,
>
> Could someone explain the reasoning behind why the following code is
> invalid?
>
> class child
> {
> public:
> void constmethod() const {}
> void nonconstmethod() {}
> };
>
> class parent
> {
> public:
> const child& mychild() const {return m_child;}
>
> private:
> child& mychild() {return m_child;}
>
> child m_child;
> };
>
> int main(int argc, char* argv[])
> {
> parent p;
> p.mychild().constmethod();
> return 0;
> }
>
> I understand that p is a non-const instance of parent but I don't
> understand why the compiler can't just resolve the mychild call to the
> public const version of the method instead of complaining it can't
> access the private version.
>
> I'm sure there's a very good reason for this, I just can't see it!
By design, overload resolution happens before the access checks.
Other designs might have worked, but are much harder to design
properly. In addition, this rule is simple. The alternative rules
would be quite complex to explain.
Usually, there is very little reason to have overload which are
mixed public/private. These overload sets are useful only to the
class implementation, and there you can be more explicit about
which method you actualy want. The class implementation is
always strongly coupled to its own interface.
HTH,
Michiel Salters
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Michiel
|
11/4/2004 12:08:03 PM
|
|
In article <REShd.7886$Ae.5152@newsread1.dllstx09.us.to.verio.net>,
Victor Bazarov <v.Abazarov@comAcast.net> writes
> Name resolution is done before checking access rights. That's just how
> things are. The resolution finds that there are two members 'mychild'.
> It sees that the object is non-const. It picks the non-const variation
> of 'mychild'. That's the extend of _name_resolution_. Then it
> verifies
> the access rights. Finds a violation. A simple two-stage process that
> is _always_ the same. Access specifiers have _no_ bearing on
> resolution
> of the names.
And this was a deliberate design decision that replacing all instances
of 'private' with 'public' should not change the semantics of a program
that compiled with the use of 'private'. I think we have changed that
guarantee since and a proposal of mine for re-opening class interfaces
will involve even more change (though ones that many people who I have
discussed it with think are beneficial).
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Francis
|
11/4/2004 3:51:33 PM
|
|
davidagal@gmail.com (David Gal) wrote
> Could someone explain the reasoning behind why the following code is
> invalid?
[snip code containing a class with a public const function and
same-named private non-const function]
> I understand that p is a non-const instance of parent but I don't
> understand why the compiler can't just resolve the mychild call to the
> public const version of the method instead of complaining it can't
> access the private version.
>
> I'm sure there's a very good reason for this, I just can't see it!
This was an early design decision in C++. You should get D&C (see the
FAQ) if you with to learn the reasoning behind this decision.
Generally, the thought went that changing an access specifier shouldn't
change the meaning of a program. If the compiler were allowed to
ignore inaccessible functions, then changing the "private" keyword
to "public" would cause code to call a completly different function.
Instead, the compiler FIRST determines which function to call, and
THEN decides if it's allowed to call it.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
allan_w
|
11/6/2004 4:06:26 PM
|
|
Thanks to all of you who took the time to respond to my question.
So it's basically just the way things are. I can see that it probably
does make sense not to have a programs semantics changed by a change
to a method's access right. It's just a bit annoying!
I'm basically writing a small framework and the class I'm writing is
used as a base class by user's of the framework. I wanted to make the
non-const version of the function private and the const version
public. Guess I'll have to use different names or something.
Thanks
David
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
davidagal
|
11/7/2004 12:08:00 PM
|
|
|
8 Replies
123 Views
(page loaded in 0.111 seconds)
|