Modifying non const attribute in const function - c++

So I have a class with the following function :
void AddNoiseToAim(Vector2D& position) const which is essentialy a utility function.
To correctly compute the noise I use a complexe object which require kind of a heavy initialisation so to avoid doing it at every call of the function, I decided to put the object as a non const attribute of the class so the initialisation is performed once at the instantiation and then used multiple time by the function.
The problem is that AddNoiseToAim is const and the attribute is not so I can't use it in the function, BUT the attribute is only used for this specific purpose so the only thing that retain me from putting it in the scope of the function is the initialisation of the object.
I thought of 3 solutions for now, the first one is to remove the const modifier of the AddNoiseToAim but I don't want to do that, since by nature this function doesn't modify the instance of the class. Second solution would be to pass the attribute as a reference to the function like it's done for the parameter position, but even that feel kind of weird, since it's like making a detour. Finally the solution I've gone with for now but which would give me memory issues is doing something like that :
void Raven_WeaponSystem::AddNoiseToAim(Vector2D& AimingPos) const
{
static FuzzyModule* fuzzyModule = InitializeFuzzyModule();
/* omitted */
}
FuzzyModule is not an attribute of the class anymore.
In my case Raven_WeaponSystem has the same life span as the application, so I don't really care about the lost memory but it really doesn't feel good.
To sum up ! I would like the function to initialize an object in its scope only once at the first call of the function OR I would like the object to be initialize outside of the function and used in the constant function (in which case my second solution should suffice).
Thanks for your time ! Cheers.

If you can't initialize fuzzyModule in the constructor, declare it mutable in the class (which will allow you to modify its value in a const function).
mutable FuzzyModule *fuzzyModule;

Related

Use function-pointer as proxy to member-function

Assume a class like this:
class Speaker {
public:
void (*saySomething)();
}
The point is that we can instantiate that class and call the stored function pointer in order to make it say something (whatever that turns out to be). The background to such an approach is to have the actual function reside in a shared library and Speaker acts as some sort of wrapper class (The function gets resolved in the library and the pointer is assigned to the variable in the class).
Now consider we have another class that extends Speaker:
class ConstantSpeaker : public Speaker {
protected:
std::string message;
void doSpeak();
}
with the method's implementation like this:
ConstantSpeaker::doSpeak() {
std::cout << message << std:endl;
}
Now I want to assign the saySomething pointer in a way so that the call is somehow re-routed to ConstantSpeaker::doSpeak(). This however isn't possible directly as doSpeak() is a member function and saySomething is a pointer to a non-member-function.
Another idea I had was to create doSpeak() as a friend-function of ConstantSpeaker instead. Then the pointer-assignment works fine but now doSpeak() would require the object holding the actual message as an argument in order to be able to access the message.
To me it seems as if there should be a (more or less) straight-forward way of doing this given that I can only ever call Speaker::saySomething when having an instance of a Speaker at hand. Therefore the availability of the corresponding object shouldn't be a problem but still I can't figure out how I have to assign that pointer.
The only solution I could come up with is to add a public virtual Speaker::doSaySomething function whose implementation will call the function pointer (which is then no longer public in order to prevent miss-usage) and that can be overwritten by ConstantSpeaker to call ConstantSpeaker::doSpeak() instead.
Is there another solution to this problem?
Another solution is just to use a standard std::function<void()>, and then it can be still declared as public.
Also, instead of bare function pointer, you can use pointer to member function, but be aware about slicing, when using it inside a base class.
But, I think, the most trivial way of doing this is just by using virtual function, like you've mentioned.
Maybe tell more about your context? What is the problem you are going to solve?

C++ const accessors and references best practice

In attempting to brush up on my C++, I've been trying to find out the best-practice way of creating accessors.
I want to clarify my understanding and find out if what I'm doing is right. I have several questions, but they seem pretty simple so I've rolled them all into this one Stack Overflow question.
The following is some example code representing what I 'think' is the correct way of doing things:
class MyClass
{
private:
std::string StringMember_;
int IntMember_;
public:
MyClass(const std::string &stringInput, const int &intInput) : StringMember_(stringInput), IntMember_(intInput)
{
}
const std::string &StringMember() const
{
return StringMember_;
}
void StringMember(const std::string &stringInput)
{
StringMember_ = stringInput;
}
const int &IntMember() const
{
return IntMember_;
}
void IntMember(const int &intInput)
{
IntMember_ = intInput;
}
};
My questions are:
Where my accessors return a const reference variable, ie const std::string, this means that it (my class's member variable) cannot be changed. Is that correct?
The last const before a method's body indicates that no members of the class for which that method is a part of can be altered, unless they are designated mutable. Is this also correct?
Where I'm passing in const method parameters, this means that I ensure these parameters are always stored as they were passed in, thus protecting any original variables being passed in from being altered by the method body. Is this also correct?
With regards to the mutable keyword, under what circumstances would I actually want to use this? I've been struggling to think of a good scenario where I'd have a const method that needed to modify class members.
Accessors seem like a good idea, even for data that will never be publicly exposed, because it ensures a single-point of entry, allowing for easier debugging and so on. Am I thinking along the right lines here, or is this in fact totally meaningless, and that there is no need for private accessors?
From a purely syntactical perspective, should I be writing my references like const int& intInput or const int &intInput. Does it really matter where the ampersand is, or is it just a matter of personal preference?
Finally, is what I'm doing in the example above good practice? I plan to start working on a larger personal project, and I want to have these core basics down before I start running into problems later.
I was using this as a reference: https://isocpp.org/wiki/faq/const-correctness
Where my accessors return a const reference variable, ie const std::string, this means that it (my class's member variable) cannot be changed. Is that correct?
Correct. A variable cannot be changed through a const reference.
The last const before a method's body indicates that no members of the class for which that method is a part of can be altered, unless they are designated mutable. Is this also correct?
Correct. It also allows the function to be called on a const object.
Where I'm passing in const method parameters, this means that I ensure these parameters are always stored as they were passed in, thus protecting any original variables being passed in from being altered by the method body. Is this also correct?
Correct. Same can be achieved with accepting the argument by value.
With regards to the mutable keyword, under what circumstances would I actually want to use this?
See When have you used C++ 'mutable' keyword?
Accessors seem like a good idea, even for data that will never be publicly exposed, because it ensures a single-point of entry, allowing for easier debugging and so on. Am I thinking along the right lines here
I don't buy this argument. Watchpoints allow for easy debugging of member variables regardless of where they're accessed from.
From a purely syntactical perspective, should I be writing my references like const int& intInput or const int &intInput.
Both are syntactically equivalent and the choice between them is purely aesthetic.
Finally, is what I'm doing in the example above good practice?
There is no general answer. Accessors are sometimes useful. Often they're redundant. If you provide a function that allows setting the value directly, such as you do here, then you might as well get rid of the accessors and make the member public.
Seems to me like you have a pretty good handle on the concepts here. As far as a mutable example there are lots, here's one: you have a search method, and for performance reasons you cache the last search results... that internal cache would need to be mutable for a const search method. I.e. the external behavior didn't change, but internally something might change.
Here is some examples for mutable:
memoiziation caches, for when something is referencially-transparent,
but expensive to calculate, the first call to the (const-qualified)
accessor calculates the value and stores it in a mutable member hash
table, second and subsequent calls fetch the value from the table
instead.
access counters, timing, loggers, and other instrumentation that needs
to change some state when a const-qualified accessor is called
From https://www.quora.com/When-should-I-actually-use-a-mutable-keyword-in-C++

How can I make a class that type-erases objects until a function is called on them without specifying the list of possible functions up front?

Background
The title probably sounds confusing, so let me explain. First of all, here is a minimal version of my implementation, so you can follow along with the concepts more easily. If you've seen some of Sean Parent's talks, you'll know he came up with a way to abstract polymorphism, allowing code such as this:
std::vector<Drawable> figures{Circle{}, Square{}};
for (auto &&figure : figures) {draw(figure);}
Notice that there are no pointers or anything. Calling draw on a Drawable will call the appropriate draw function on the contained object without the type of the object being easily accessible. One major downside to this is that similar classes to Drawable have to be written for each task. I'm trying to abstract this a bit so that the function does not have to be known by the class. My current solution is as follows:
std::vector<Applicator<Draw>> figures{Circle{}, Square{}};
for (auto &&figure : figures) {figure.apply(Draw{});}
Here, Draw is a functor with an operator()(Circle) and opeator()(Square), or a generic version. In this way, this is also sort of a visitor pattern implementation. If you wanted to also, say, print the name of each figure, you could do Applicator<Draw, PrintName>. When calling apply, the desired function is chosen.
My implementation works by passing a boost::variant of the callable types to the virtual function and having it visit that variant and call the function within. Overall, I would say this implementation is acceptable, but I haven't yet thought much about allowing any number of parameters or a return type, let alone ones that differ from function to function.
Question
I spent days trying to think of a way to have this work without making Applicator a template. Ideally, the use would be more similar to this. For the sake of simplicity, assume the functions called must have the signature void(ObjectType).
//For added type strictness, I could make this Applicator<Figure> and have
//using Figure<struct Circle> = Circle; etc
std::vector<Applicator> figures{Circle{}, Square{}};
for (auto &&figure : figures) {figure.apply(Draw{});} //or .apply(draw); if I can
The problem usually comes down to the fact that the type of the object can only be obtained within a function called on it. Internally, the class uses virtual functions, which means no templates. When apply is called, here's what happens (identical to Sean's talks):
The internal base class's apply is called on a pointer to the base class with the runtime type of a derived class.
The call is dispatched to the derived class, which knows the type of the stored object.
So by the time I have the object, the function to call must be reduced to a single type known within the class that both knows which function to call and takes the object. I cannot for the life of me come up with a way to do this.
Attempts
Here are a couple of failed attempts so you can see why I find this difficult:
The premise for both of the first two is to have a type that holds a function call minus the unknown first argument (the stored object). This would need to at least be templated on the type of the callable object. By using Sean Parent's technique, it's easy enough to make a FunctionCall<F> class that can be stored in a GenericFunctionCall, much like a Circle in a Figure. This GenericFunctionCall can be passed into the virtual function, whereas the other cannot.
Attempt 1
apply() is called with a known callable object type.
The type of the callable object is used to create a FunctionCall<Type> and store it as a type-erased GenericFunctionCall.
This GenericFunctionCall object is passed to the virtual apply function.
The derived class gets the call object and has the object to be used as the first argument available.
For the same reason of virtual functions not being allowed to be templates, the GenericFunctionCall could call the necessary function on the right FunctionCall<Type>, but not forward the first (stored object) argument.
Attempt 2
As a continuation of attempt 1:
In order to pass the stored object into the function called on the GenericFunctionCall, the stored object could be type-erased into a GenericObject.
One of two things would be possible:
A function is called and given a proper FunctionCall<Type>, but has a GenericObject to give to it, with the type unknown outside of a function called on it. Recall that the function cannot be templated on the function call type.
A function is called and given a proper T representing the stored object, but has a GenericFunctionCall to extract the right function call type from. We're back where we started in the derived class's apply function.
Attempt 3
Take the known type of a callable object when calling apply and use it to make something that stores a function that it can call with a known stored object type (like std::function).
Type-erase that into a boost::any and pass it to the virtual function.
Cast it back to the appropriate type when the stored object type is known in the derived class and then pass the object in.
Realize that this whole approach requires the stored object type to be known when calling apply.
Are there any bright ideas out there for how to turn this class into one that doesn't need the template arguments, but can rather take any callable object and call it with the stored object?
P.S. I'm open for suggestions on better names than Applicator and apply.
This is not possible. Consider a program composed of three translation units:
// tu1.cpp
void populate(std::vector<Applicator>& figures) {
figures.push_back(Circle{});
figures.push_back(Square{});
}
// tu2.cpp
void draw(std::vector<Applicator>& figures) {
for (auto &&figure : figures) { figure.apply(Draw{}); }
}
// tu3.cpp
void combine() {
std::vector<Applicator>& figures;
populate(figures);
draw(figures);
}
It must be possible for each TU to be translated separately, indeed in causal isolation. But this means that at no point is there a compiler that simultaneously has access to Draw and to Circle, so code for Draw to call Circle::draw can never be generated.

Is there any way to change the scope of a callback without changing the paramaters?

I am using SDL2_mixer library, but I believe that the question should hold for the general case also.
Currently, a function that I would like to use, Mix_HookMusicFinished(void (*music_finished)(void)) has a set callback to the global scope for a C style function. However, I would like to have that callback be set to a member function within my own class void CMusic::musicFinished() without having the need for a function in global scope.
Is there anyway to do this? Something like Mix_HookMusicFinished(musicFinished) would be great, but that directly has an error of argument of type "void (CMusic::*)()" is incompatible with parameter of type "void (*)()"
You need to make a "wrapper" function. However, the problem here is that you also need to be able to find the CMusic object that you want to "finish" - this is really what the crux of
argument of type ... is incompatible with ...
is all about. Since there is no way to pass a parameter to the musicFinished object, you will need some other way of "finding" the CMusic object.
If we assume there is a way to do that, then something like this would work:
class CMusic
{
...
public:
...
static void musicFinishedWrapper();
void musicFinished();
...
};
void CMusic::musicFinishedWrapper()
{
CMusic* music = getTheMusicSomehow(); // No idea how you do this - depends on your code.
music->musicFinished();
}
The reason you have to have a CMusic object is that your musicFinished expects a (hidden) this pointer argument - which is the value in music in my little function.
You could move musicFinished to your CMusic class and declare it as a static class method. static class methods aren't called on an object; they therefore don't have an implicit argument to specify the value of the this pointer, and they therefore can have the same signature as freestanding functions. You additionally can make it private to prevent anything but CMusic from using it.
However, since your musicFinished method currently works as a freestanding function and therefore probably doesn't need access to CMusic's protected or private members, and since your efforts to limit its scope presumably means that you don't want other things to call it, I personally would leave your musicFinished function as freestanding but declare it as static (or move it to an anonymous namespace, if you prefer) within the CMusic source (.cpp or .cc) file. Doing so would restrict its scope to the source file (the "compilation unit"). An advantage over a private, static class method is that it does not need to be exposed at all in a header file, so it is in some sense more private.

how can I use a non static instance in a static method in c++?

I have a an instance of lasse1 and I want to use it in a method of lasse2 , this method is static method, this just doesn't work :
class Lasse2{
......
public :
static void function(void);
Lasse1* obj;
........
};
And now i want to use it like :
void Lasse2::function(void){
obj->dosmt(); // this doesn't work
.........
any idea how can I solve this?
If you want to access an instance member of your class, then you must have an instance of that class. There's no way around this. Your options are:
Make obj a static member. Do this if you intend to have a single obj for all instances of this class.
Remove static from function() so it becomes an instance method.
If you can't do either of those, then you need to find a way to pass an instance pointer to your function. For example, APIs that require a function pointer often have a mechanism for passing pointer-sized data to that function when it's eventually called.
Change your static method to explicitly pass the object pointer:
static void function(Lasse1* obj)
{
obj->dosmt();
}
But before you do, consider what you're really trying to do (and even write another question if you like).
You need an instance of your class to pull that off.
Create one or receive it through other means (function argument, global variable, class static variable, etc)
SLaks said it best: "You can't"
Here's why:
When you declare a member variable (not static, see obj above), you're telling the compiler that each object of type Lassie2 contains a pointer to a Lassie1.
When you declare a method static, that means that it is independent of all the instances (the actual objects) of that class. It doesn't operate on an object.
So inside of Lasse2::function, there's no this, no Lassie2 object for you to get the obj pointer from.