My problem is not serious,
its just a question about the most beautifull solution.
Maybe somebody has a better idea!
I have a mathematical class having some numerical functions.
It is convenient for me, and speed up the program,
if I introduce a member array called "memory",
and store the values of the previous calling.
(for example Maple can do the same)
Before this solution my function has the const qualifier,
but now it cannot be const, because I write in the memory.
Its ok for a programmer,
but its not logical to a mathematician,
since I only get values with the calling of that function.
If I use my class as a member in another class,
I cannot call the non const function from another const function,
which is inconvenient also.
An other solution is to use global memory variables,
but I have not just one object from the same class,
so I cannot use the same global variable.
Therefore this solution is dirty also. Any idea? Thanks

Recommended Answers

All 14 Replies

Please elaborate...

Lets say, we have a class with a member function:

Now the function write the data member memory,
therefore cannot be const;
This is my problem, because esentially its just a function,
which calculate a result, and do not change anything,
except the memory.
Its also inconvenient,
if I have another class which has mylass as data member:

class otherclass{
  myclass obj;
public:
  void otherfunc();
};

void otherclass::otherfunc()
{
  ...
  obj.myfunc(x,y,z);
  ...
}

in this case otherfunc cannot be const also,
and the user will be surprised,
because I dont want that the user know that I use memory,
he want to use the numeric function only.

Onother solution is using global memory variable.
But its not good, if I want to use lots of representation
of the same class: myclass.

So any other solution? Or can we restrict const qualifier to user defined datas? Or mimic the same effect?

Sorry about my previous post, lets start again:

Lets say, we have a class with a member function:

class myclass{
...
public:
  double myfunc(double x1, double x2, double x3) const;
};

We assume that myfunc does lots of calculations,
and we can save runtime if we backup the previous result.
Therefore we introduce memory like this:

class myclass{
  vector<double> memory;
public:
  double myfunc(double x1, double x2, double x3);
};

double myclass::myfunc(double x1, double x2, double x3)
{
  double result;
  result = ...
  memory[0] = x1;
  memory[1] = x2;
  memory[2] = x3;
  memory[3] = result;
  return result;
}

Now the function write the data member memory,
therefore cannot be const;
This is my problem, because esentially its just a function,
which calculate a result, and do not change anything,
except the memory.
Its also inconvenient,
if I have another class which has mylass as data member:

I would question how you are using the vector to store the results. How will you differentiate between results from different functions, or worst results from different functions that take different numbers of parameters?

Anyway your storage scheme aside I see 2 possible solutions. You could declare memory mutable. A mutable data member can have its value changed by a const function. However you need to be careful and use mutable in a good semantic way. The data objects that get changed should not be a aprt of the state of the object and I think that may be they are in this case.

I use mutable when I declare mutex objects in classes to protect multithreaded access, the mutex is not part of the classes state it is just protecting code that should only be run by 1 thread at a time such as getters which would normally be const.

The other option is to have a separate class to store the results, you can then call out to that class from your const function, remember a const function only says that the class data will not change. Soemthing like this

class resultCache
{
  vector<double> memory;

public:
    void storeResult(double x1, double x2, double x3, double result)
    {
      memory[0] = x1;
      memory[1] = x2;
      memory[2] = x3;
      memory[3] = result;
    }

};

class myclass{
resultCache* prc;

public:
  double myfunc(double x1, double x2, double x3) const;
  myclass():
  prc(new resultCache)
  {
  }

};

double myclass::myfunc(double x1, double x2, double x3) const
{
  double result = 12.5;

  prc->storeResult(x1, x2, x3, result);

  return result;
}

Thank you! Clever ideas!
I dont know "mutable", but its OK, thank you.

As I see, your second solution relies on
that we declare memory not as a data,
but a pointer to a data.
In this case we do not change the pointer,
therefore function can be const.
But in this case outsider can change memory,
if they know its adress.

A also think of a third solution:
creating a global memory table,
which is a map from class -> data,
but my problem is, that I cannot create map of references,
and copying the whole class to the map is no good.
I want to avoid pointer,
because outsider can change the value of the data.
It is possible to mimic references somehow,
kind if ID for example,
and create the memory table?

const is a some what overrated concept that leads to more typing
and maintenance.

In your case myfunc is not const as it alters a member variable
if this is not appropriate to be altered then you need to use a local

double myfunc(double x1,double x2, double x3) const
{
std::vector<double> memory(4, 0.0);
//etc...
}

but your function does not necessarily want this either...
the const is telling the compiler that you are not altering the class
but that is what you are doing and there is no way that the compiler can resolve this problem.

There might be a way to cast the function to const but I don't know it...

the question is why does the other end need to know that your class variable is const....
it should not matter it is only that x1, x2, x3 are not changing that should matter where the function is called! so there is no logical need for the function to be declared const only the inputs!

const is a some what overrated concept that leads to more typing
and maintenance.

In your case myfunc is not const as it alters a member variable
if this is not appropriate to be altered then you need to use a local

double myfunc(double x1,double x2, double x3) const
{
std::vector<double> memory(4, 0.0);
//etc...
}

but your function does not necessarily want this either...
the const is telling the compiler that you are not altering the class
but that is what you are doing and there is no way that the compiler can resolve this problem.

There might be a way to cast the function to const but I don't know it...

the question is why does the other end need to know that your class variable is const....
it should not matter it is only that x1, x2, x3 are not changing that should matter where the function is called! so there is no logical need for the function to be declared const only the inputs!

I wonder did you read the previous posts at all?

const is not an overrated feature that increases typing. It is an invaluable feature that allows a programmer to specify a semantic constraint, i.e. that a particular object should not be modified. const allows a programmer to communicate to both compilers and other programmers that a value should remain invariant. Wherever this is true you should say so. Doing so you gain help from the compiler in making sure the constraint isn't violated. It is generally considered good practice to use const wherever possible.


I wonder did you read the previous posts at all?

Yes. Yet again you are jumping on a single sentence and basing your entire response on that basis.

I have several maths functions and if you are encapsulating them in a class rather than global functions you would get something like:

#include "../my_maths/my_maths_functions.h"

double my_class::my_function(const double x1, const double x2) const
{
 my_maths_functions m;
 //altering m  but not x1 and x2
 double ret = m.myfunc(x1, x2, x3);
 return ret + 2.0;
}

this is a valid const function using myfunc non const

It does not matter that m is altering and you might want more than
one at once in a multi-threaded environment so a global is undesirable for such a generic class

the thing to note is that the class my_maths_functions should not have fixed member variables and it would be contained rather than inherited from by its essence of purpose.

const is used to declare a design purpose and there is no need for your maths_functions to be in a class using func() const;

your variables should be const because you want to leave them unaltered but the function for a maths class does not have this need.

Yes. Yet again you are jumping on a single sentence and basing your entire response on that basis.

I have several maths functions and if you are encapsulating them in a class rather than global functions you would get something like:

#include "../my_maths/my_maths_functions.h"

double my_class::my_function(const double x1, const double x2) const
{
 my_maths_functions m;
 //altering m  but not x1 and x2
 double ret = m.myfunc(x1, x2, x3);
 return ret + 2.0;
}

this is a valid const function using myfunc non const

It does not matter that m is altering and you might want more than
one at once in a multi-threaded environment so a global is undesirable for such a generic class

the thing to note is that the class my_maths_functions should not have fixed member variables and it would be contained rather than inherited from by its essence of purpose.

const is used to declare a design purpose and there is no need for your maths_functions to be in a class using func() const;

your variables should be const because you want to leave them unaltered but the function for a maths class does not have this need.

Without seeing more of the OPs code we are unable to make general comments on his design. I have merely pointed out that your advice re. const is incorrect and provided a reason as to why it is incorrect.

As banfa pointed out in his post the OP may be able to reasonably maintain the constness of his class through the use of mutable. Without deeper knowledge of the design and usage of the class it is difficult to comment onthe rights or wrongs of this design choice. But to recommend that const is an overrated source of typing and extra manintenance is simply wrong. So I pointed it out.

an overrated

not an accurate quote!
the use of an adjective somewhat makes a big difference. you limit your answers to the university answers with little regard for the real life situations that occur with programming either large scientific or several professional programming projects.

The const is there to stop amateur slips but when you use a method you should know what its intent is before you use it. you will find many times in life that an accessor is not declared const or an iterator is used and reintroducing const_iterator will take significant time to alter.

If a method might reasonably alter a class but doesn't currently...
Declaring it const and then altering it back can lead to extensive coding changes.

You will notice that a lot of the example code you see doesn't include const because of convenience of typing. But using const is a design decision.

1 - "I have a mathematical class having some numerical functions."
2 - "It is convenient for me"

Both of these statements give a fixed scope of the problem
and although you do get maths class which store local variables that are fixed for an equation they are not designed to persist unaltered so

const my_maths_functions m(0.3, 0.5);

is unusual as any method called that alters the variables should be unambiguous. it is down to the name.

2 - this is a design decision you want so stick to it.

not an accurate quote!
the use of an adjective somewhat makes a big difference. you limit your answers to the university answers with little regard for the real life situations that occur with programming either large scientific or several professional programming projects.

The const is there to stop amateur slips but when you use a method you should know what its intent is before you use it. you will find many times in life that an accessor is not declared const or an iterator is used and reintroducing const_iterator will take significant time to alter.

If a method might reasonably alter a class but doesn't currently...
Declaring it const and then altering it back can lead to extensive coding changes.

You will notice that a lot of the example code you see doesn't include const because of convenience of typing. But using const is a design decision.

1 - "I have a mathematical class having some numerical functions."
2 - "It is convenient for me"

Both of these statements give a fixed scope of the problem
and although you do get maths class which store local variables that are fixed for an equation they are not designed to persist unaltered so

const my_maths_functions m(0.3, 0.5);

is unusual as any method called that alters the variables should be unambiguous. it is down to the name.

2 - this is a design decision you want so stick to it.

You are right that retro fitting constness to a design is a pain. That is why it is an important decision which should not be left until late in the design process. It is good practice to always consider constness right from the start for that very reason.

The const is there to stop amateur slips but when you use a method you should know what its intent is before you use it.

This is complete rubbish. If you design a class and then hand that class off to a user then you can't assume anything about the how they will use it or the level of knowledge they will gain before attempting to use it. Therefore you should do all you can to enforce your design constraints. Be assured that if you don't someone will attempt to use the class in a manner you did not intend.

if professionals are all above misusing a class, and all learn by rote all the signatures of every function that they ever employ, then I wonder why professionally written libraries always pay close attention to constness.

Touchy aren't you?

As I see, your second solution relies on
that we declare memory not as a data,
but a pointer to a data.
In this case we do not change the pointer,
therefore function can be const.
But in this case outsider can change memory,
if they know its adress.

If they know its address but since it is a private member of myclass they have no way of getting its address.

A also think of a third solution:
creating a global memory table,
which is a map from class -> data,
but my problem is, that I cannot create map of references,
and copying the whole class to the map is no good.
I want to avoid pointer,
because outsider can change the value of the data.
It is possible to mimic references somehow,
kind if ID for example,
and create the memory table?

Any solution relying on global data is likely to have problems and will certainly break the design pardgim of encapsulation (not to mention what if they get a pointer to that global data and alter it?) Additionally you seemed to be inferring that there would be more than one instance of myclass which would each need there own separate store which would be hard to do with global memory.

You also seem to infer that references somehow don't have the problem that pointers have when it comes to external access to the data. However this stored data will still be in memory somewhere weather or not there is a pointer to it. That means it will still have an address and if the outside user can get the address they will still be able to read/alter it.

If it is that important that the external memory can not read/alter the data then you need to store it in an encrypted form, not try and obfuscate the pointer to it.

Touchy aren't you?

...

professionally written libraries always pay close attention to constness.

Wasn't talking libraries I am talking in-house software to create .exe
with 100,000s of lines of code, which I guess from your comments you have rarely worked on.

A library has to work with 3rd party classes so it has to be const to comply with others use and although believing in-house software should be written this way is noble, it doesn't take people into account.

If you design a class

The reason that I keep responding to you is that you are missing the critical issue and detracting from the solution as a result.

This whole problem is about design. If the OP rightly feels that a class needs to have a memory block but doesn't want to declare a temporary like I showed in my first class. Then this is not a set
of const functions in the class.

The declaration of a const function is meaningless in mathematics. It only has meaning in computing so the OP is needlessly worrying that the change won't make sense to the users being mathemaricians.

It is where the const needs to be placed for clarity. As he is copying by values the input to the function, there is limited need for const, but a const might be added to the variables as that does have a mathematical meaning.

- The only question that cannot be answered without knowing the class and functions is whether the OP is correct to want a memory block. And I am assuming that it is a reasonable decision especially since OP states that it is working. Therefore, the request for alternative designs is missing the bigger design issue.

...


Wasn't talking libraries I am talking in-house software to create .exe
with 100,000s of lines of code, which I guess from your comments you have rarely worked on.

A library has to work with 3rd party classes so it has to be const to comply with others use and although believing in-house software should be written this way is noble, it doesn't take people into account.


The reason that I keep responding to you is that you are missing the critical issue and detracting from the solution as a result.

This whole problem is about design. If the OP rightly feels that a class needs to have a memory block but doesn't want to declare a temporary like I showed in my first class. Then this is not a set
of const functions in the class.

The declaration of a const function is meaningless in mathematics. It only has meaning in computing so the OP is needlessly worrying that the change won't make sense to the users being mathemaricians.

It is where the const needs to be placed for clarity. As he is copying by values the input to the function, there is limited need for const, but a const might be added to the variables as that does have a mathematical meaning.

- The only question that cannot be answered without knowing the class and functions is whether the OP is correct to want a memory block. And I am assuming that it is a reasonable decision especially since OP states that it is working. Therefore, the request for alternative designs is missing the bigger design issue.

The mathematicians using his class are still programmers are they not?

Look you are missing to point too. Everything else you say may be true, but your initial statement that const is an overrated concept is extrememly poor advice. It implies that more experience programmers disregard constness because they know better, which is complete nonsense. Like saying that a learner driver should wear a seatbelt but a professional probably doesn't have to bother because he wont crash. That is all I am pointing out.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.