How to force a call for an inspector

  • Thread starter Przemyslaw Koprowski
  • Start date
P

Przemyslaw Koprowski

Hi all,

Imagine you have a class, containing two methods
with the same name (say 'get'), but one being an
inspector the other mutator - the class contains
a kind of data structure (vector in the example below,
but more complicated in the real-life example) and
for 'incorrect' calls the inspector returns zero
but the mutator expands the storage.

Now imagine that this function is called from inside
another method (say 'foo') which is a mutator (and must
be such) but that should not change the size of data
structure described above. How to force this method
to call the INSPECTOR 'get' (and prevent the expansion
of data structure).

Example code at the end of this post.

I have two ideas but I hope that there is a better
solution:
a) make the method 'foo' const and make all the parts
it changes mutable - but I don't like it, in the
real-life case I have in mind this will obscure the code
and sure abuse the mutab keyword
b) use two names for inspector/mutator get - this is
what I do right now, but it has disadvantages: the methods
cannot be operators () or [] then, it may be unclear for
users of the code why these two methods have different names.

Thus, I will apreciate any suggestions. Thanks in advance,
Przemek


Example code:
============
#include <iostream>
#include <vector>
#include <stdexcept>

class A {
private:
// some container e.g. a vector
std::vector<int> vec;
// whatever else
int bar;
public:
// example c-tor
A() : vec(10, 0) {};
// two get methods
int get(int) const;
int & get(int);
// another method that MUST be mutator
void foo(int);
//...
};

// inspector get
// return 0 outside the storage space
int A::get(int i) const
{
if( i < 0 ) throw std::eek:ut_of_range("A::get");
if( static_cast<unsigned>(i) >= vec.size() ) return 0;
return vec;
}

// mutator get
// EXPANDS the storage when accesing past the end
int & A::get(int i)
{
std::cout << "mutator get here" << std::endl;
if( i < 0 ) throw std::eek:ut_of_range("A::get");
if( static_cast<unsigned>(i) >= vec.size() )
vec.resize(i + 1, 0);
return vec;
}

// a method that MUST be mutator
void A::foo(int i)
{
// this calls mutator 'get'
// but how to call the inspector???
bar += get(i);
}

int main()
{
A a;
a.foo(15);
return 0;
}
 
J

jkherciueh

Przemyslaw said:
Hi all,

Imagine you have a class, containing two methods
with the same name (say 'get'), but one being an
inspector the other mutator - the class contains
a kind of data structure (vector in the example below,
but more complicated in the real-life example) and
for 'incorrect' calls the inspector returns zero
but the mutator expands the storage.

Now imagine that this function is called from inside
another method (say 'foo') which is a mutator (and must
be such) but that should not change the size of data
structure described above. How to force this method
to call the INSPECTOR 'get' (and prevent the expansion
of data structure).

Example code at the end of this post.

I have two ideas but I hope that there is a better
solution:
a) make the method 'foo' const and make all the parts
it changes mutable - but I don't like it, in the
real-life case I have in mind this will obscure the code
and sure abuse the mutab keyword
b) use two names for inspector/mutator get - this is
what I do right now, but it has disadvantages: the methods
cannot be operators () or [] then, it may be unclear for
users of the code why these two methods have different names.

Thus, I will apreciate any suggestions. Thanks in advance,
Przemek


Example code:
============
#include <iostream>
#include <vector>
#include <stdexcept>

class A {
private:
// some container e.g. a vector
std::vector<int> vec;
// whatever else
int bar;
public:
// example c-tor
A() : vec(10, 0) {};
// two get methods
int get(int) const;
int & get(int);
// another method that MUST be mutator
void foo(int);
//...
};

// inspector get
// return 0 outside the storage space
int A::get(int i) const
{
if( i < 0 ) throw std::eek:ut_of_range("A::get");
if( static_cast<unsigned>(i) >= vec.size() ) return 0;
return vec;
}

// mutator get
// EXPANDS the storage when accesing past the end
int & A::get(int i)
{
std::cout << "mutator get here" << std::endl;
if( i < 0 ) throw std::eek:ut_of_range("A::get");
if( static_cast<unsigned>(i) >= vec.size() )
vec.resize(i + 1, 0);
return vec;
}

// a method that MUST be mutator
void A::foo(int i)
{
// this calls mutator 'get'
// but how to call the inspector???
bar += get(i);


try

bar += const_cast< A const * >( this )->get(i);


However: the use of the cast may indicate a deeper design problem.
}

int main()
{
A a;
a.foo(15);
return 0;
}


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top