Const and noncost accessor methods.

  • Follow


Here is a minimal program illustrating an accessor method, ie get():

/************************ BEGIN *********************************************/
#include <iostream>
using namespace std;

class foo
{
	public:

		int* get()
		{
			cout << "get\n";
			return a;
		}

		const int *get() const
		{
			cout << "get - const \n";
			return a;
		}
		
	private:
		int a[1];
};

int main()
{
	foo f;

	*f.get() = 3;

	const int* i=f.get();

	cout << *i << endl;

	const foo& g = f;
	
	cout << *g.get() << endl;
};



/********************************** END *************************************/



The output if this program is:

get
get
3
get - const
3

How come the second get isn't get-const, since get() is being used as an rvalue
and is being assigned to a const int?

Is there any way to make the program use the const accessor when the accessor is
being used is a const context?

The reason that I ask is that I am trying to make an image class which implements
a copy-on-write scheme and used operator[]() to access the pixels. However, 
even though I've provided a const and non-const version of [], when I try to 
access the pixels for reading, the non-const accessor is called which causes
a copy to occur (since the class thinks a write is occuring).

Can anyone offer any help?

Thanks

-Ed

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply u98ejr 11/8/2003 12:50:24 AM

Edward Rosten wrote:


 > How come the second get isn't get-const, since get() is being used as an rvalue
 > and is being assigned to a const int?

That's because your f object is not const, while the g object is const.

 >
 > Is there any way to make the program use the const accessor when the accessor is
 > being used is a const context?

Yes.  Use a proxy class.  See S. Meyer's "More Effective C++" Item 30
"Proxy Classes".

Basically, instead of returning the int* value directly, return an
object of your proxy class, that can then be converted implicitly to
int*.  Of course, you need to overload the appropriate assignment,
conversion, etc. operators.
However, this technique has some disadvantages in certain circumstances
that are mentioned in Meyer's book.

HTH,
Jack




      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Frank 11/8/2003 1:29:45 PM


Frank Gore <frank.gore@gmx.net> wrote
 > Edward Rosten wrote:
 >  > How come the second get isn't get-const, since get() is being used
 >  > as an rvalue and is being assigned to a const int?
 >
 > That's because your f object is not const, while the g object is const.

Right. When you use .get() in an expression, the context is not
evaluated. f.get() always evaluates to the same thing, regardless
of whether it's on the right-hand-side of an assignment or the
left-hand side, or anything else.

(There are some compilers with non-standard extensions to this.
Visual C++ 6.0 has a concept called "properties," which was an
early form of what Microsoft later included in the C# language.
But this is not part of portable C++.)


 >  > Is there any way to make the program use the const accessor
 >  > when the accessor is being used is a const context?
 >
 > Yes.  Use a proxy class.  See S. Meyer's "More Effective C++" Item 30
 > "Proxy Classes".

An excellent technique, and Meyers explains it very well. Basically
it involves returning something that can be CONVERTED either to
a reference or value as needed.

But there is another technique you should consider, one that's easier
to read and write and even more efficient. All you have to do is
allow the user to make the choice. Provide TWO access functions,
one that's const and one that can mutate. Replace get with:

     int get_a() const { return a; } // Returned by value - read only
     int &mod_a() { return a; }      // The user can modify this one

Your users call get_a() most of the time; they call mod_a() when they
will need to modify your foo object. If you're using copy-on-write,
the second version is the only one that needs to trigger a deep copy.

(Note: Most of the time, your public interface should not return a
pointer to private data.)

      [ 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/11/2003 4:45:58 PM

2 Replies
316 Views

(page loaded in 0.003 seconds)

Similiar Articles:





7/26/2012 9:04:30 PM


Reply: