jima@hplsla.HP.COM (Jim Adcock) (07/18/89)
Is there a way to declare a member function const -- IE to tell the compiler that the member function does not change the value of this nor *this ???
ark@alice.UUCP (Andrew Koenig) (07/18/89)
In article <6590205@hplsla.HP.COM>, jima@hplsla.HP.COM (Jim Adcock) writes: > Is there a way to declare a member function const -- IE to tell the compiler > that the member function does not change the value of this nor *this Yes [in 2.0]: class foo { int n; public: void setsize(int k) { n = k; } int getsize() const { return n; } }; If you say `const' in the declaration, and the definition isn't in the same place, you must also say `const' in the definition: class bar { int n; public: void setsize(int); int getsize() const; }; void bar::setsize(int k) { n = k; } void foo::getsize() const { return n; } In a member function defined with `const' this way, `this' is a pointer to a constant object. It is meaningless to say `const' for a constructor or destructor: they can operate on constants anyway. -- --Andrew Koenig ark@europa.att.com
mhyman@hsfmsh.UUCP (Marco S. Hyman) (07/18/89)
In article <6590205@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: > Is there a way to declare a member function const -- IE to tell the compiler > that the member function does not change the value of this nor *this > > ??? Release 2.0 supports the following: (according to Lippman's book) class x { ... type func() const {...}; } I don't know if it's supported in G++ as I haven't tried it yet. --marc -- //Marco S. Hyman //UUCP: ...!sun!sfsun!hsfmsh!mhyman //Domain: sfsun!hsfmsh!mhyman@sun.com
daniel@avsd.UUCP (Daniel Edelson) (07/19/89)
>In article <6590205@hplsla.HP.COM>, jima@hplsla.HP.COM (Jim Adcock) writes: > >> Is there a way to declare a member function const -- IE to tell the compiler >> that the member function does not change the value of this nor *this In article <9633@alice.UUCP> ark@alice.UUCP (Andrew Koenig) responds: > >Yes [in 2.0]: > > class foo { > int n; > public: > void setsize(int k) { n = k; } > int getsize() const { return n; } > }; > >In a member function defined with `const' this way, `this' is >a pointer to a constant object. >-- > --Andrew Koenig > ark@europa.att.com Why is this feature useful? Is it to improve code readability by making it clear when a member function does not alter any member data? Is there also a reliability motivation? RE: jima's other question, is there also a syntax for specifying that `this' is a constant pointer rather than a pointer to a constant object? How about this? struct S { int x; void cmf() const; }; void put(S *p) { cin >> p->x; } void look(const S *p) { cout << p->x; } void S::cmf() const { put(this); // illegal, put() takes a "S *" but `this' is a "const S *" look(this); // legal, look() takes a "const S *", which `this' is this=this; // legal, `this' is of type "const S *", not "S *const" } Is this correct? Daniel Edelson Currently: daniel@avsd.UUCP (Ampex Corporation, Redwood City, CA) And also: daniel@saturn.ucsc.edu (Univ. of Calif., Santa Cruz)
jima@hplsla.HP.COM (Jim Adcock) (07/20/89)
>Why is this feature useful? Is it to improve code >readability by making it clear when a member function does not alter any >member data? yes. >Is there also a reliability motivation? yes. A compiler can check that the const is not violated. Also, if one tried to pass by reference a const object to a non-const function, a compiler may generate a copy of that const object so that the non-const function can't molest it. This keeps FORTRAN-like problems from happening where that constant 2 you passed by reference gets changed by the routine to actually be 5. More importantly, using const in all the right places now lets me get rid of most of those annoying warning messages when I run +w :-)
ark@alice.UUCP (Andrew Koenig) (08/15/89)
In article <1771@avsd.UUCP>, daniel@avsd.UUCP (Daniel Edelson) writes: > Why is this feature useful? Is it to improve code readability > by making it clear when a member function does not alter any > member data? Is there also a reliability motivation? The motivation is to give `const' consistent semantics. For example: class Foo { private: int x; public: Foo() { x = 0; } void set(int n) { x = n; } int get() { return x; } }; void f() { const Foo a; int n = a.get(); // legal a.set(7); // legal or not? } If `const' is to mean anything useful for class objects, there must be some notion of whether or not calling a member function changes the object. Here, Foo::set() changes the object but Foo::get() doesn't. Because Foo::set() changes the object, you'd like the line marked `legal or not?' to be flagged as an error. But that's impossible in general because the definitions of Foo::set() and Foo::get() might have been separately compiled. Therefore C++2.0 lets you say this: class Foo { private: int x; public: Foo() { x = 0; } void set(int n) { x = n; } int get() const { return x; } }; The `const' in the definition of Foo::get() says that it's OK to call Foo::get() on a constant object. Therefore, { const Foo a; int n = a.get(); // legal a.set(7); // illegal } The line marked `illegal' is illegal because `a' is a const object and Foo::set() can't be called for a constant. > RE: jima's other question, is there also a syntax for specifying > that `this' is a constant pointer rather than a pointer to a > constant object? There's no syntax for saying that `this' is a constant pointer. However, assignment to `this' is deprecated; some future version of C++ will uniformly treat `this' as a constant pointer. > How about this? > struct S { > int x; > void cmf() const; > }; OK so far, S::cmf is a member that can be called on a const object. > void put(S *p) { cin >> p->x; } > void look(const S *p) { cout << p->x; } No problems here. > void S::cmf() const > { > put(this); // illegal, put() takes a "S *" but `this' is a "const S *" > look(this); // legal, look() takes a "const S *", which `this' is > this=this; // legal, `this' is of type "const S *", not "S *const" > } Right you are. I'll reiterate, though, that saying `this=this' is a dangerous anachronism and should be avoided and ultimately eliminated. In fact, I'm not sure what purpose it serves if it's not in a constructor or destructor. -- --Andrew Koenig ark@europa.att.com