Recasting const function - c++

I'm using a library (libtcod) that has an A* pathfinding algorithm. My class inherits the callback base class, and I implement the required callback function. Here is my generic example:
class MyClass : public ITCODPathCallback
{
...
public: // The callback function
float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const
{
return this->doSomeMath();
};
float doSomeMath() { // non-const stuff }
};
I found a number of examples using const_cast and static_cast, but they seemed to be going the other way, making a non-const function be able to return a const function result. How can I do it in this example?
getWalkCost() is defined by my library that I cannot change, but I want to be able to do non-const things in it.

The best solution depends on why you want to do non-const stuff. For example, if you have a cache of results that you want to use to improve performance, then you can make the cache be mutable, since that preserves the logical constness:
class MyClass : public ITCODPathCallback
{
...
public: // The callback function
float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const
{
return this->doSomeMath();
};
float doSomeMath() const { // ok to modify cache here }
mutable std::map<int,int> cache;
};
Or perhaps you want to record some statistics about how many times the getWalkCost was called and what the maximum x value was, then passing a reference to the statistics may be best:
class MyClass : public ITCODPathCallback
{
...
public:
struct WalkStatistics {
int number_of_calls;
int max_x_value;
WalkStatistics() : number_of_calls(0), max_x_value(0) { }
};
MyClass(WalkStatistics &walk_statistics)
: walk_statistics(walk_statistics)
{
}
// The callback function
float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const
{
return this->doSomeMath();
};
float doSomeMath() const { // ok to modify walk_statistics members here }
WalkStatistics &walk_statistics;
};

You can hack it this way:
return const_cast<MyClass*>(this)->doSomeMath();
Of course this won't be considered good design by most people, but hey. If you prefer you can instead make doSomeMath() const, and mark the data members it modifies as mutable.

Related

Modifying a data of type "static const int* const" from a member function

TLDR Question:
class MyClass
{
public:
void Modify()
{
//How can I modify MyData here
}
public:
static const int* const MyData;
};
Lore:
I have a class like this:
class Window
{
public:
const int* GetKeyboard()
{
return m_Keyboard;
}
private:
const int* const m_Keyboard = 0;
};
With this I would access keyboard as WindowObjectPtr->GetKeyboard() but I want to access it as Input::Keyboard. So I wrote something like this:
class Window
{
public:
const int* GetKeyboard()
{
return m_Keyboard;
}
private:
const int* const m_Keyboard = 0;
};
const int* Input::Keyboard = 0;
class Application;
class Input
{
friend class Application;
private:
static void SetKeyboard(const int* k) { Keyboard = k; }
public:
static const int* Keyboard;
};
class Application
{
public:
void Init()
{
Input::SetKeyboard(m_Window.GetKeyboard());
}
private:
Window m_Window;
};
int main()
{
Application application;
application.Init();
//Input::Keyboard
}
The only problem with the above code is that I can do Input::Keyboaord = nullptr;
So I want to change definition of keyboard to static const int* const Keyboard; but then Input::SetKeyboard cannot set it anymore.
Is there a valid version of something like mutable static const int* const Keyboard; ? or a different method of achieving what I am trying to do?
Either an object is const or it isn't. If it is const it must be given a value in its initialization and any attempt at changing it later will cause undefined behavior (if it isn't ill-formed to begin with).
There is no way to make an object const after a certain other point in the execution flow.
Of course you can just add a const reference to the object and use that whenever you don't intent to modify it for const-correctness:
static const int* Keyboard;
static const int* const& cKeyboard = Keyboard;
Now Keyboard can be used for modification and cKeyboard can't (without const_cast trickery).
But that all seems like completely avoidable and messy, since you could just have Keyboard be a non-static member, have Application have a non-static Input member and then have all initialization happen in the constructor's initializer lists. Then there wouldn't be a problem with having Keyboard be const-qualified at all.
Many things can be hacked.
For example you can have a constant static member which references a private non-static member. The private member can be initialized and set later by a friend. The public member can only be used to read:
#include<iostream>
struct foo {
static const int& x_public;
friend class bar;
private:
static int x_private;
};
const int& foo::x_public = foo::x_private;
int foo::x_private = 0;
struct bar {
bar() {
foo::x_private = 42;
}
};
int main() {
bar b;
std::cout << foo::x_public;
}
Thgouh, I am not really suggesting to use this. I agree with this answer that you should rather use a non-static member.

RAM-efficient C++ property

A property is a public data member of a class, which can be accessed by client code. And the owning object receives a notification (in the form of get/set notification callback) whenever the client code reads or modifies the property.
Some languages (like C#) have built-in properties.
I want to create a property for C++ that will be RAM-efficient.
The most obvious way to make a property is something like this:
class Super;
struct Prop {
Prop( Super * super ) : m_super(*super), m_a(0) {}
int operator=( int a );
operator int() const;
int m_a;
Super & m_super;
};
struct Super {
Super() : one(this), two(this) {}
void onSet() { printf("set"); }
void onGet() { printf("get"); }
Prop one;
Prop two;
};
int Prop::operator=( int a ) { m_super.onSet(); m_a = a; return a; }
Prop::operator int() const { m_super.onGet(); return m_a; }
Trouble is - every property has to keep a pointer to the outer class which I consider costly.
I want to know if there is a more RAM-efficient way to do this?
For example, if all Super-classes are generated, is it allowed by the Standard to get a pointer to the outer class from this pointer of the property?
Something like this:
struct Prop {
Prop( uint8_t offset ) : m_offset(offset), m_a(0) {}
int operator=( int a );
operator int() const;
int m_a;
const uint8_t m_offset;
};
int Prop::operator=( int a ) {
Super * super = (Super *)( ((char *)this) + m_offset);
super->onSet(); m_a = a; return a;
}
struct Super {
// assuming exact order of properties
Super() : one(0), two(sizeof(Prop)) {}
void onSet() { printf("set"); }
void onGet() { printf("get"); }
Prop one;
Prop two;
};
Since this offset is a constant expression it (theoretically) can be kept in ROM (or at least it can be smaller than sizeof(pointer)).
Or maybe there is another way?
c++ has properties as language extension
Look no further, msvc has support.
clang compiler also supports this syntax. Im not sure about gcc.
Storing offset can be also be done
Just, in the constructor calculate the offset from this, ala. :
Prop( Super& super ) {
uint8_t offset = this - std::addressof(super );//somewhat unmaintable - but may save some bytes
}
then when used, calculate back using this
Please note the space saving may be less than it seems due to alignment and padding.
I obviously don't know the context of your code, so this may be inconceivable in your specific implementation, but you could do something like
class Prop(){
Prop() : m_a(0){};
int operator=(int a){m_a = a;};
int m_a;
}
class Super(){
public:
int set_prop(int index, int value){
m_props[index] = value;
onSet();
return value;
}
private:
void onSet(){};
std::vector<Prop> m_props;
}
Obviously you need to initialize the vector and handle error cases etc but the logic is there - if you only access the props through the super.
That leaves you with purely the size of the sequence of structs with no pointers back to the super.

C++ : How to ensure that a class member variable is modifiable only within a certain method

I am using C++ 14 with clang on MacOS Sierra. I want to enforce a rule by design. Following is the rule.
I have a member variable in my class say:
unsigned int m_important_num;
There are 4 methods in my class.
fun1();
fun2();
fun3();
fun4();
Objective:
I want only fun2() to be able to change the value of m_important_num.
Question:
Is it possible to make it compiler error if any method other than fun2() changes the variable?
One possible way is to declare it const somehow empower fun2() to change const variables? Is this a good solution? Or are their any better solutions?
Secondary question:
Is it a wrong design to try do such a thing?
Sort of, with additional layer:
class S1 {
public:
void fun2() { /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
unsigned int m_important_num;
};
class S2 : private S1
{
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
As Yakk commented, if func2 need access to S2 members, CRTP can solve that:
template <typename Derived>
class S1 {
public:
void fun2() { asDerived().foo3(); /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
Derived& asDerived() { return stataic_cast<Derived&>(*this); }
private:
unsigned int m_important_num;
};
class S2 : private S1<S2>
{
// friend class S1<S2>; // If required.
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
Encapsulate it down. Put m_important_num in its own class. Aggregate it in your existing class. Have a getter for it. Then put fun2() as a member function of your inner class.
I little variant (if I understand correctly) of the Jeffrey solution: put the variable in an inner class and make it private; create a public getter and make func2() friend to the inner class.
I mean
struct foo
{
int f1 () { return b0.getVal(); }; // you can read `val` everywhere
void f2 () { b0.val = 42; }; // you can write `val` in f2()
void f3 () { /* b0.val = 42; ERROR ! */ }; // but only in f2()
class bar
{
private:
int val = 24;
public:
int getVal () { return val; }
friend void foo::f2 ();
};
bar b0;
};
In other words: friend is your friend.
If you want to prevent a method from modifying any member in the class you can use the trailing const identifier:
class something{
private:
unsigned int var;
public:
void fun1() const;
void fun2();
void fun3() const;
void fun4() const;
}
Here, only fun2() will be able to modify the variable.
I know there are lots of good answers, but there is also an option that you sort of alluded to in your question:
One possible way is to declare it const somehow empower fun2() to change const variables?
#include <iostream>
using uint = unsigned int;
class Test
{
const uint num;
public:
Test(uint _num)
:
num(_num)
{}
uint get_num() const
{
return num;
}
void can_change_num(uint _new_num)
{
uint& n(const_cast<uint&>(num));
n = _new_num;
}
void cant_change_num(uint _new_num)
{
// num = _new_num; // Doesn't compile
}
};
int main()
{
Test t(1);
std::cout << "Num is " << t.get_num() << "\n";
t.can_change_num(10);
std::cout << "Num is " << t.get_num() << "\n";
return 0;
}
Produces
Num is 1
Num is 10
You already got lots of good answers to your primary question. I'll try to address the secondary one.
Is it a wrong design to try do such a thing?
It's hard to say w/o knowing more about your design. In general anything like this detected during a code review would raise a big red flag. Such a protection makes sense in a case of a big class with convoluted logic/implementation. Otherwise why would you like to go an extra mile and make your code much more complicated? The fact you seek for this can indicate your class became unmanageable.
I'd recommend to consider splitting it to smaller parts with better defined logic where you won't worry such mistakes can happen easily.

How do I repass a function pointer in C++

Firstly, I am very new to function pointers and their horrible syntax so play nice.
I am writing a method to filter all pixels in my bitmap based on a function that I pass in. I have written the method to dereference it and call it in the pixel buffer but I also need a wrapper method in my bitmap class that takes the function pointer and passes it on. How do I do it? What is the syntax? I'm a little stumped.
Here is my code with all the irrelevant bits stripped out and files combined (read all variables initialized filled etc.).
struct sColour
{
unsigned char r, g, b, a;
};
class cPixelBuffer
{
private:
sColour* _pixels;
int _width;
int _height;
int _buffersize;
public:
void FilterAll(sColour (*FilterFunc)(sColour));
};
void cPixelBuffer::FilterAll(sColour (*FilterFunc)(sColour))
{
// fast fast fast hacky FAST
for (int i = 0; i < _buffersize; i++)
{
_pixels[i] = (*FilterFunc)(_pixels[i]);
}
}
class cBitmap
{
private:
cPixelBuffer* _pixels;
public:
inline void cBitmap::Filter(sColour (*FilterFunc)(sColour))
{
//HERE!!
}
};
If I understand what you want:
inline void cBitmap::Filter(sColour (*FilterFunc)(sColour))
{
_pixels->FilterAll( FilterFunc);
}
Often dealing with function pointers can be made easier to read if you use a typedef for the function pointer type (yours actually isn't too bad on its own - they can get much worse very easily):
struct sColour
{
unsigned char r, g, b, a;
};
typedef
sColour (*FilterFunc_t)(sColour); // typedef for a FilterFunc
class cPixelBuffer
{
private:
sColour* _pixels;
int _width;
int _height;
int _buffersize;
public:
void FilterAll(FilterFunc_t FilterFunc);
};
void cPixelBuffer::FilterAll(FilterFunc_t FilterFunc)
{
// fast fast fast hacky FAST
for (int i = 0; i < _buffersize; i++)
{
_pixels[i] = (*FilterFunc)(_pixels[i]);
}
}
class cBitmap
{
private:
cPixelBuffer* _pixels;
public:
inline void cBitmap::Filter(FilterFunc_t FilterFunc)
{
_pixels->FilterAll( FilterFunc);
}
};
The Boost libraries can make your life easier here. see boost function.
For example here is a function that takes a call back function that takes two ints and returns an int:
void do_something( boost::function<int (int, int)> callback_fn );
Then it can be used like a normal function:
int result = callback_fn(1,2);
Pass it to do_something like this:
boost::function<int (int, int)> myfn = &the_actual_fn;
do_something(myfn);
With boost function you can also pass class member functions easily (see boost bind).
Good luck with your program.
You could make things clearer by using a typedef for your function pointer type:
typedef sColour (*FilterFunc_t)(sColour)
void FilterAll(FilterFunc_t FilterFunc);
Passing a variable containing a function pointer to a different function works the same as passing any other variable:
inline void cBitmap::Filter(FilterFunc_t FilterFunc) {
FilterAll(FilterFunc);
}

raw function pointer from a bound method

I need to bind a method into a function-callback, except this snippet is not legal as discussed in demote-boostfunction-to-a-plain-function-pointer.
What's the simplest way to get this behavior?
struct C {
void m(int x) {
(void) x;
_asm int 3;
}};
typedef void (*cb_t)(int);
int main() {
C c;
boost::function<void (int x)> cb = boost::bind(&C::m, &c, _1);
cb_t raw_cb = *cb.target<cb_t>(); //null dereference
raw_cb(1);
return 0;
}
You can make your own class to do the same thing as the boost bind function. All the class has to do is accept the function type and a pointer to the object that contains the function. For example, this is a void return and void param delegate:
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
Usage:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
Now, since VoidDelegate<C> is a type, having a collection of these might not be practical, because what if the list was to contain functions of class B too? It couldn't.
This is where polymorphism comes into play. You can create an interface IDelegate, which has a function Invoke:
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
If VoidDelegate<T> implements IDelegate you could have a collection of IDelegates and therefore have callbacks to methods in different class types.
Either you can shove that bound parameter into a global variable and create a static function that can pick up the value and call the function on it, or you're going to have to generate per-instance functions on the fly - this will involve some kind of on the fly code-gen to generate a stub function on the heap that has a static local variable set to the value you want, and then calls the function on it.
The first way is simple and easy to understand, but not at all thread-safe or reentrant. The second version is messy and difficult, but thread-safe and reentrant if done right.
Edit: I just found out that ATL uses the code generation technique to do exactly this - they generate thunks on the fly that set up the this pointer and other data and then jump to the call back function. Here's a CodeProject article that explains how that works and might give you an idea of how to do it yourself. Particularly look at the last sample (Program 77).
Note that since the article was written DEP has come into existance and you'll need to use VirtualAlloc with PAGE_EXECUTE_READWRITE to get a chunk of memory where you can allocate your thunks and execute them.
#include <iostream>
typedef void(*callback_t)(int);
template< typename Class, void (Class::*Method_Pointer)(void) >
void wrapper( int class_pointer )
{
Class * const self = (Class*)(void*)class_pointer;
(self->*Method_Pointer)();
}
class A
{
public:
int m_i;
void callback( )
{ std::cout << "callback: " << m_i << std::endl; }
};
int main()
{
A a = { 10 };
callback_t cb = &wrapper<A,&A::callback>;
cb( (int)(void*)&a);
}
i have it working right now by turning C into a singleton, factoring C::m into C::m_Impl, and declaring static C::m(int) which forwards to the singleton instance. talk about a hack.