On 18 Apr., 03:33, t.wa...@[EMAIL PROTECTED]
wrote:
> I'm trying to slowly convert some C code to C++ and have encounter
> what's probably a trivial problem.
>
> The easiest way to describe the problem is with an example:
>
> class FOO
> {
> public:
> int Version(void){return m_ver;};
Version is a member function without const qualifier.
Thus you cannot invoke this function on a const object
or on a reference or pointer to const Version.
Additionally, while formally correct, most programmers
would remove the void parameter from above parameter
list, because in C++ it does not add anything useful
to the function signature. Note also that the final semicolon
is optional here.
To solve your problem, you want to change the signature
of this function to
int Version(void) const {return m_ver;};
or to
int Version() const {return m_ver;}
> FOO(){m_ver = 1;};
> private:
> int m_ver;
> };
>
> void PrintVer(const FOO * fp)
> {
> int v = fp->Version(); /* error here */
>
> cout << "The version is " << v << endl;
> }
Given above modification this should compile now.
Considering that PrintVer could not work reasonably
with a NULL pointer argument, you could consider to
modify the definition of PrintVer as well using references
instead:
void PrintVer(const FOO& fp)
{
int v = fp.Version();
//...
}
> If I remove the const from the routine declaration, it works fine, but
> I'd rather not do that. I guess I don't understand what the compiler
> is trying to tell me, and have no idea of how to work around this
> without removing the const.
If you add the const qualifier as shown above, you are promising
that PrintVer will not modify any data member directly and that
you can only invoke any member function with const qualifier
or free function with pointers/references to const. It's easier to
understand this constraint, if you would assume for a while that
your *original* Version would not be a member function, but a free
or static member function, like this
int Version(FOO& arg){return arg.m_ver;}
ignoring here that such free function could usually not access the
m_ver data member.
Now consider your function PrintVer function, which would invoke
this function:
void PrintVer(const FOO& fp)
{
int v = Version(fp);
//...
}
If the compiler would allow this, then it would be very easy to
break the const guarantee that PrintVer has given, because
PrintVer says "I do not allow modifications". This is so, because
given the non-const signature (either as member function or as
free or static member function) you could similarly write
int Version(FOO& arg){return ++arg.m_ver;}
but if you declare Version as
int Version(const FOO& arg){return ++arg.m_ver;}
the compiler would reject this code immediately.
In short: A const-qualified member function behaves like
a normal function, where you have added one further argument
of reference to const class type. In fact, most - if not all -
compilers will represent non-static member functions in
that or a similar way.
Last but not least: The same reasoning applies to the volatile-
qualifier or any cv-combination as well.
HTH & Greetings from Bremen,
Daniel Krügler
--
[ See http://www.gotw.ca/resources/clcm.htm
for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


|