|
From: Daniel Krügler on 17 Apr 2008 21:13 On 18 Apr., 03:33, t.wa...(a)nci-sw.com 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! ]
From: Thomas J. Gritzan on 17 Apr 2008 21:13 t.wanat(a)nci-sw.com schrieb: > 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 All uppercase names are reserved for macros. So you should rename it to Foo. > { > public: > int Version(void){return m_ver;}; Make this a const member function. That will fix the problem. Empty parameter lists usually are written as () in C++, while as (void) in C. int Version() const { return m_ver; } > FOO(){m_ver = 1;}; Prefer initialization lists to assignment in constructors: F() : m_ver(1) {} > private: > int m_ver; > }; > > void PrintVer(const FOO * fp) In C++, you prefer references to pointers: void PrintVar(const FOO& foo) > { > int v = fp->Version(); /* error here */ > > cout << "The version is " << v << endl; > } > > When I try to compile, I get the error > 'FOO::Version' cannot convert 'this' pointer from 'const FOO' to 'FOO > &' > > on the line containing 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. -- Thomas http://www.netmeister.org/news/learn2quote.html :wq [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Lionel B on 17 Apr 2008 21:13 On Thu, 17 Apr 2008 19:33:58 -0600, t.wanat 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;}; // ^ ^ // drop the "void" extraneous ";" int Version() const {return m_ver;} // ^ // add this > FOO(){m_ver = 1;}; // ^ // extraneous ";" > private: > int m_ver; > }; > > void PrintVer(const FOO * fp) > { > int v = fp->Version(); /* error here */ > > cout << "The version is " << v << endl; } > > When I try to compile, I get the error 'FOO::Version' cannot convert > 'this' pointer from 'const FOO' to 'FOO &' > > on the line containing fp->Version(). This is because "const FOO * fp" declares a pointer to a const FOO object; so *fp cannot be modified in the function PrintVer(). But the function FOO::Version() does not guarantee that the FOO object it is invoked on will not be modified, so the compiler complains. You can guarantee that FOO::Version() will not modify its invoking object by declaring it "const" (see above). Note that declaring the parameter to PrintVer() as "FOO* const fp" would also solve your problem; it says that the *pointer* fp is const (rather than the object it points to). It depends what you want, really... if the function FOO::Version() really does not modify its invoking object it should be declared const; and if PrintVer() does not modify the pointer fp *or* the object it points to (as I suspect is your case), then the parameter should probably be declared as "const FOO* const fp". > 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. Hope this helps, -- Lionel B [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Gerhard Menzl on 17 Apr 2008 21:13 t.wanat(a)nci-sw.com wrote: > class FOO > { > public: > int Version(void){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; > } > > When I try to compile, I get the error > 'FOO::Version' cannot convert 'this' pointer from 'const FOO' to 'FOO > &' > > on the line containing 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. When you have a pointer to a const object, you can only call const member functions via this pointer. Your compiler is trying to tell you that FOO:Version should be changed to: int Version() const { return m_ver; } (the void is a C-ism and unnecessary). Version() does not change the state of FOO, hence it should be const. As an aside, all-caps identifiers should be reserved for preprocessor macros if you want to avoid name clashes. -- Gerhard Menzl Non-spammers may respond to my email address, which is composed of my full name, separated by a dot, followed by at, followed by "fwz", followed by a dot, followed by "aero". [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Lehmann on 18 Apr 2008 08:16 > class FOO > { > public: > int Version(void){return m_ver;}; > FOO(){m_ver = 1;}; > private: > int m_ver; > }; > > void PrintVer(const FOO * fp) Defining a parameter as const usually results by the decision not to change the content of that parameter. Calling 'Version' the none const method can change the content of FOO and that's why the compiler yells. Change (a) 'int Version()' to 'int Version() const' or (b) remove the const from the parameter in 'PrintVer'. I would prefer the first variant. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: auto_ptr for array of built-ins Next: assignment operator using a constructor |