Value of constant variable can be changed through pointer tricks, but is it possible to do something like this :
class A (){
int x;
public:
void func () const {
//change value of x here
}
}
declare x mutable
class A (){
mutable int x;
public:
void func () const {
//change value of x here
}
};
You have two options:
class C
{
public:
void const_f() const
{
x = 5; // A
auto* p_this = const_cast<C*>(this); // B
p_this->y = 5;
}
private:
mutable int x; // A
int y;
};
A: declare certain members mutable.
B: const_cast to remove constness from the this pointer.
Though this is not appreciated, but C++ provides “Backdoors” which can be used to breach its own regulations, just like dirty pointer tricks. Anyway, you can easily do this by using a casted version of “This” pointer :
class A (){
int x;
public:
void func () const {
//change value of x here
A* ptr = const_cast<A*> (this);
ptr->x= 10; //Voila ! Here you go buddy
}
}
The most important thing to understand here is bitwise/physical/concrete constness and conceptual/meaningwise/logical/abstract constness.
In short:
If the function is conceptually const, make the member data mutable.
Otherwise, make the function non-const.
Just cast 'this', this would be a dirty way to implement your program, do avoid this if you are doing a project or teamwork as others would get confused by this.
class CAST_CLASS (){
int var;
public:
void change_CAST () const {
CAST_CLASS* pointer = const_cast<CAST_CLASS*> (this);
pointer->var= 10;
}};
The other answers don't mention this, but following also modifies "x" (definitely, not advisable):
class A {
int x, &y{x}, *z{&x};
public:
void func () const
{
y = 42; // x is modified now!
*z = 29; // x is modified again!!
}
};
Related
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.
i was wondering if is possible make that a method of class points to another method of other class:
consider this:
// Class Foo:
class Foo
{
static int GetA(int a);
static int GetB(int b);
};
int Foo::GetA(int a)
{
return a * 2;
}
int Foo::GetB(int b)
{
return a * 4;
}
// Hooking class methods:
class HookFoo
{
static int HookGetA(int);
static int HookGetB(int);
};
int(HookFoo::*HookGetA)(int) = (int(HookFoo::*)(int))0x0; // (0x0 Memory address) or for example: &Foo::GetA;
int(HookFoo::*HookGetB)(int) = (int(HookFoo::*)(int))0x0; // (0x0 Memory address) or for example: &Foo::GetA;
I know it's possible do some like:
int(*NewHook)(int) = &Foo::GetA;
but how i can do for declare the methods into of a class?
Here is more or less what you tried to achieve (minimal, working example):
class Foo
{
public:
static int GetA(int a);
static int GetB(int b);
};
int Foo::GetA(int a)
{
return a * 2;
}
int Foo::GetB(int b)
{
return b * 4;
}
class HookFoo
{
public:
using FuncType = int(*)(int);
static FuncType HookGetA;
static FuncType HookGetB;
};
// Initialized with Foo::GetA
HookFoo::FuncType HookFoo::HookGetA = &Foo::GetA;
// nullptr'ed
HookFoo::FuncType HookFoo::HookGetB = nullptr;
int main() {
HookFoo::HookGetA(0);
}
For the methods in Foo are static, you can use a simple function pointer type to refer to them. You don't have to use (and can't use actually) a member function pointer in this case.
The using declaration helps to have a more readable code.
When you have correctly initialized your hooks, you can invoke them (thus the pointed functions) as you can see in the main.
I added a couple of visibility specifiers for your methods and data members were all private.
You can use function pointers.
Ex:
class A {
public:
static void say_hello() { cout << "Hello\n"; }
};
class B {
public:
static void(*hook)();
};
void(*B::hook)() = A::say_hello;
int main()
{
B::hook();
}
If you need to hook into functions at a specific address, use a function pointer. You can't reassign functions like that
// typedef your function pointers, it makes the syntax a lot easier
typedef int(*FHook)(int);
class HookFoo
{
static FHook HookGetA;
static FHook HookGetB;
};
// assign to address
FHook HookFoo::HookGetA = (FHook)0x1234;
FHook HookFoo::HookGetB = (FHook)0x5678;
Of course its your job to make sure the addresses are correct.
the explicit function pointer types would be as such:
class HookFoo
{
static int (*HookGetA)(int);
static int (*HookGetB)(int);
};
int (*HookFoo::HookGetA)(int) = (int(*)(int))0x1234;
int (*HookFoo::HookGetB)(int) = (int(*)(int))0x5678;
I'm looking for a way to have an int variable that persists value across method calls. From this perspective a class member will be good.
But I would like that int variable to be changed in only one particular method.
How do I make that?
I tough about
void MyClass::my_method(){
static int var = 0;
var++;
}
But, I would like var = 0; to be executed only the first time.
void my_method(){
static int var;
var++;
}
The problem here is, that
static int var;
is only visible in the local scope of my_method().
You can make it global just by definition of that variable outside of my_method():
int var;
void my_method() {
var++;
}
but var will be visible for everyone.
The better way is to encapsulate all of that into a class:
class MyClass {
public:
static void my_method() {
var++;
}
private:
static int var = 0;
};
You can use the following key access pattern:
struct Foo {
void fun1();
void fun2();
static class Var {
friend void Foo::fun1();
int i = 0;
public:
int value() const { return i; }
} var;
};
Foo::Var Foo::var;
void Foo::fun1() { var.i = 42; }
void Foo::fun2() {
// var.i = 42; // this will generate compile error cause fun2 doesn't have to var
}
Live Demo
This way only the member functions of Foo that are declared friends in wrapper class Var can change its private member variables (e.g., var.i).
var is just locally, if you want that to be 0 the first time the function returns make it initialized to -1 or if 0 is just right you are ok. As is var is only visible inside my_method so if you want that to be visible to all the class you have to put it outside and use only my_method to modify the value.
I don't have enough rep to comment yet, But you should note that Static is not equal to Constant.
Static variables maintain their value for ALL instances of a class, whereas Constant variables can have different values for each instance (object) of a class.
See this question for a more in-depth explanation.
What is the difference between a static and const variable?
To answer your question directly, you cannot have a true "Global" vairable that is only editable from one class. Instead, you should consider πάντα ῥεῖ 's answer OR wait to declare the constant until after you know the value you would like to assign to it. For instance, I want to store X+10 to a constant variable Y
int x = 5 //create variable
//Do whatever you need to do to get the value
function myFunction(){
x = x + 10;
}
const int y = x; //now Y = 15 and cannot be changed.
Consider the following code:
struct data
{
int foo;
int bar;
};
data a;
a.foo = 200;
a.bar = 300;
static void update(data* a, int rspec)
{
if (!rspec) //my data management
{
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(a->foo);
3rdPartyApi->PushData(a->bar);
3rdPartyApi->CloseStream();
}
else // internal data management
{
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(3rdPartyApi->BufferQueue);
3rdPartyApi->CloseStream();
}
3rdPartyApi->PushStream(3rdPartyApi->GetLastStreamBuffer().POD());
}
Lets say I change the value of a.foo or a.bar, and it requires me to call Update there-after the assignment. Can this be done, without actually calling Update() on each change manually?
[EDIT]
Note that the update function created is also assigned to a function pointer for
the third party API, so it can do it's own internal updating. So making the update function non-global is impossible, and thus is why the current update function is global.
[EDIT]
I also rewrote my example to be more understanding and correct to the actual API I'm using
e.g
3rdPartyApi->StreamUpdate((void (*)(void*, int))update);
Yes, you can. Use class methods for this. Pass a static method from your class to the 3rd party API as an update function.
class data
{
public:
void set_foo(int new_foo);
void set_bar(int new_bar);
int get_foo() const;
int get_bar() const;
// This is the update signature which the 3rd party API can accept.
static void update(void* ptr, int rspec);
private:
// These are private so we can control their access.
int foo;
int bar;
};
void data::set_foo(int new_foo)
{
foo = new_foo;
// 'this' is a special pointer for current data object.
update(this);
}
void data::set_bar(int new_bar)
{
bar = new_bar;
update(this);
}
int data::get_foo() const
{
return foo;
}
int data::get_bar() const
{
return bar;
}
// This is needed if the 3rd party API can only call C bindings.
// If it's a C++ API this is not needed.
extern "C" {
void data::update(void* ptr, int rspec)
{
if (!rspec) //my data management
{
// You have to cast to data* from void*.
data* data_ptr = reinterpret_cast<data*>(ptr);
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(data_ptr->foo);
3rdPartyApi->PushData(data_ptr->bar);
3rdPartyApi->CloseStream();
}
else // internal data management
{
3rdPartyApi->CreateStream();
3rdPartyApi->PushData(3rdPartyApi->BufferQueue);
3rdPartyApi->CloseStream();
}
3rdPartyApi->PushStream(3rdPartyApi->GetLastStreamBuffer().POD());
}
} /* extern "C" */
Then:
3rdPartyApi->StreamUpdate(&data::update);
data a;
a.set_foo(200);
a.set_bar(300);
Note that use of a struct instead of a class is equally fine here. But the convention is to use classes in C++. There is only a minor difference which you can learn later.
It is hard to write code for foo, bar, and data, so let's make it more concrete:
class point
{
public:
int x_coord() const;
int y_coord() const;
void move_to(int new_x, int new_y);
private:
void update_3rd_party();
int x;
int y;
};
void point::move_to(int new_x, int new_y)
{
x = new_x;
y = new_y;
// whatever else needs to be done
update_3rd_party();
}
You need to make use of Observer design pattern or a slight variant of it.
See this example here.
The usual way would be to turn foo and bar into some type that overloads the assignment operator:
class updated_int {
int value;
public:
updated_int(int init = 0) : value(init) {}
updated_int &operator=(int new_val) {
value = new_val;
update();
return *this;
}
// You might want to declare this private and not implement it.
updated_int &operator=(updated_int const &r) {
value = r.value;
update();
return *this;
}
operator int() { return value; }
};
struct data {
updated_int foo;
updated_int bar;
}
data a;
a.foo = 1; // operator= will call update() automatically.
I have a struct:
struct s
{
UINT_PTR B_ID;
};
s d;
d.B_ID=0x1;
That works fine, but I want d.B_ID to be constant. I tried to use (const) but it didn't work. So after I put a value to d.B_ID, then I want make it a constant.
Any ideas?
EDIT
ok i don't want the whole struct a constant.
when i set timer and use the b.B_ID as an idea for the timer.
in the
switch(wparam)
{
case b.B_ID // error: B_ID must be constant
....
break;
}
so that is why i need it to be a constant
Variable modifiers are fixed at compile time for each variable. You may have to explain the context of what you are trying to do, but perhaps this will suit your needs?
struct s
{
int* const B_ID;
};
int main (void) {
int n = 5;
s d = {&n};
int* value = d.B_ID; // ok
// d.B_ID = &n; // error
return 0;
}
Since you are using C++ I would recommend:
class s {
public:
int* const B_ID;
s (int* id) :
B_ID (id) {
}
};
void main (void) {
int n = 5;
s my_s_variable = s(&n);
int* value = my_s_variable.B_ID; // ok
//my_s_variable.B_ID = &n; // error
return 0;
}
Ramiz Toma: well i need way to do it using the s.B_ID=something
In C/C++ type modifiers (like const) are declared at run time for a given type and cannot be changed at run time. This means that if a variable is declared const it can never be assigned to using the assignment operator. It will only be assigned a value when it is constructed.
This is not a problem however because you can always get around this by proper design.
If you say you need to use assignment, I assume that this is because you create the struct before you know what the value of the variable will be. If this is the case then you simply need to move the struct declaration till after you know the value.
For example
s d; //variable declaration
//calculate B_ID
//...
int* n = 5;
//...
d.B_ID = &n;
This will not work, because if you want b.D_ID to be 'un assignable' it will always be so. You will need to refactor your code similarly to:
//calculate B_ID
//...
int* n = 5;
//...
s d (&n);
//good
struct s
{
s() : B_ID(0){}
UINT_PTR const B_ID;
};
int main(){
s d;
d.B_ID=0x1; // error
}
EDIT: Sorry, here is the updated code snippet in C++
struct s
{
s(UINT_PTR const &val) : B_ID(val){}
UINT_PTR const B_ID;
};
int main(){
s d(1);
d.B_ID=0x1; // error
}
In C++ language the case label must be built from an Integral Constant Expression (ICE). ICE is what the compiler implies under the term "constant" in your error message. A non-static member of a class cannot be used in an ICE. It is not possible to do literally what you are trying to do. I.e. it is not possible to use a struct member in a case label.
Forget about switch/case in this context. Use ordinary if branching instead of switch statement.
You can't do that - ie. it is not possible to selectively make a single member of a struct const. One option is to 'constify' the entire struct:
s d;
d.B_ID=0x1;
const s cs = s; // when using this B_ID won't be modifiable - but nor would any other members
Or you could set it at construction:
struct s
{
s(UINT_PTR const p): B_ID(p) {}
UINT_PTR const B_ID;
};
s d(0xabcdef);
Another way would be a getter and a one time setter
class s
{
private:
bool m_initialized;
UINT_PTR m_value;
public:
s() : m_initialized(false), m_value(NULL) {}
s(UINT_PTR value) : m_initialized(true), m_value(value) {}
//no need for copy / assignment operators - the default works
inline UINT_PTR GetValue() const { return m_value; } //getter
bool SetValue(UINT_PTR value) //works only one time
{
if (m_initialized)
{
m_value = value;
m_initialized=true;
return true;
}
else
{
return false;
}
}
inline bool IsInitialized() const { return m_initialized; }
};