c++ member function access private static variable? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does it mean to have an undefined reference to a static member?
I don't know why I got error "undefined reference to `TT::i'" if I implement the function outside of class declaration?
Here is the code..
class TT{
private:
static int i;
public:
void t();
};
void TT::t(){
i=0;
}

It's nothing to do with where you defined the function, it's that you didn't define the static member variable, you only declared it. You need to put its definition outside the class, e.g.
int TT::i;

undefined reference to `TT::i'
is because you havent defined the static data member outside class. All static data members have to be defined outside class before using them.
class TT
{
private:
static int i;
public:
void t();
};
void TT::t()
{
i=0;
}
int TT::i=0; // define it outside the class. and if possible initialize

Static variables are saved in a different part of memory than any instance of a class. This is because they are not a PART of an instance of any class.
The code below compiles because the function t is never called.
class TT
{
private:
static int i;
public:
void t()
{
i=0;
}
};
int main(int argc, char *argv[])
{
qWarning() << "hi";
TT * t = new TT();
//t->t();
return 0;
}
However, this code doesn't complie, because t is called
class TT
{
private:
static int i;
public:
void t()
{
i=0;
}
};
int main(int argc, char *argv[])
{
qWarning() << "hi";
TT * t = new TT();
t->t();
return 0;
}
You are allowed to have undefined references you don't use in C++ (and C for that matter). For some reason, I am unsure of, the compiler seems to think this code is referencing i, when the stuff above that complies was not referencing it until called (any ideas as to why)?
class TT
{
private:
static int i;
public:
void t();
};
//int TT::i = 0;
void TT::t(){
i=0;
}
Functional example, with the static defined:
class TT
{
private:
static int i;
public:
void t();
};
int TT::i = 0;
void TT::t(){
i=0;
}

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.

Class method points to other method of other class

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;

initialize struct array as c++ class member

I have class
Class A{
};
typedef struct
{
const char *dec_text;
void (A::*TestFun)();
} Test ;
Test _funs[] = {{"testLogOK", &A::testLogOK},
{"testLoginException", &A::testLoginException}
};;
How can i initialize this Test Array in construct method. The _funs tracks the A's method name and corresponding address, the methods which like:
void (methodName) (void)
In construction method, both below ways fail:
_funs = {{"testLogOK", &A::testLogOK},
{"testLoginException", &A::testLoginException}
};
The other question is how can i invoke the function pointer.. I tried the way like:
int
A::run (const char *name, int argc, ACE_TCHAR *argv[])
{
for(int i=0; i< sizeof(_funs)/sizeof(Test); i++){
Test test = _funs[i];
*(test.testFun)(); //this->*(test.fun)(); Both fail with same error
//(this->*(test.fun))() works
}
}
The compile also fails with message:
error C2064: term does not evaluate to a function taking 0 arguments
[UPdate]
I removed the struct Test and Test _funs out of Class A. But still have problem in A's method:
int A::run (const char *name, int argc, ACE_TCHAR *argv[])
The testLogOK and testLoginException method do exist as member functions of class A
Try this:
class A
{
public:
struct Test
{
const char *dec_text;
void (A::*TestFun)();
};
A(Test tt[])
{
for (int i=0; tt[i].dec_text; i++)
_funs[i] = tt[i];
}
void f1() { printf("this is f1\n"); }
void f2() { printf("this is f2\n"); }
void f3() { printf("this is f3\n"); }
Test _funs[100];
};
A::Test tt[] =
{
{ "Function f1", &A::f1},
{ "Function f2", &A::f2},
{ "Function f3", &A::f3},
{0, 0}
};
void test()
{
A a(tt);
(a.*(a._funs[0].TestFun))();
A *pa = new A(tt);
(pa->*(pa->_funs[1].TestFun))();
delete pa;
// EDIT: call f3
(a.*(tt[2].TestFun))(); // this will call directly from the global table
}
This will invoke the function assigned to the pointer.
This can be improved quite a bit if you typedef the pointer to the member
typedef void (A::*PF_T)();
and use a std::map as container:
std::map<std::string, PF_T> func_map;
It can be streamlined a lot more, but I hope it helps up to this point.

C++: how to get element defined in a different function of same class?

I defined a class in the header file like this:
class myClass
{
public:
void test();
void train();
private:
bool check;
}
Then in the cpp file, I did this:
void myClass::test()
{
int count = 9;
//some other work
}
void myClass::train()
{
int newValue = count;
....
}
Then without surprise, I got an error saying count is not defined. So what I want to do is in my train function use the count value that is defined in the test. Is there any good way to do this without using any additional dependencies? Thank you.
Well yes. That's called a member variable. Exactly like your bool check;.
Do
private:
bool check;
int count;
and then use it directly in your functions.
void myClass::test()
{
count = 9;
//Same as this->count = 9;
}
void myClass::train()
{
int newValue = count;
//Same as int newValue = this->count;
}
In your example, when method test finishes its work, count variable does not exist anymore, so there's no way of accessing it. You have to ensure, that its lifetime will be long enough to be accessed from another place. Making it a class field solves the problem (this is what class fields are for :)).
Do it this way:
class myClass
{
public:
void test();
void train();
private:
bool check;
int count; // <- here
}
and then
void myClass::test()
{
count = 9;
//some other work
}
But that's not the only solution. You can do it in another way, say:
class myClass
{
public:
int test()
{
// do some work
return 9;
}
void train(int count)
{
int newValue = count;
}
}
// (somewhere)
myClass c;
int count = c.test();
c.train(count);
That all depends on what test, train and count are for...

How to access static class variable in static member function of same class?

I provide my sample:
class a
{
public:
static int m_n;
static int memfuc();
};
int a::memfuc()
{
int k =m_n;
return k;
}
But the following sample throws linker error: unresolved external symbols
You haven't defined (as opposed to declared) your static class member variable.
You could put this code in an implementation file (.cpp) somewhere:
int a::m_n = 123456;
You need to provide the implementation somewhere:
int a::m_n;
For a static, you have to define it as :
class a
{
public:
static int m_n;
static int memfuc();
};
int a::m_n = 0;
int main()
{
a my_a;
}
my2c
You need to define the member m_n, but you also need to access the member correctly.
You need to add:
int a::m_n = 0 // Or some number of your choice
Now m_n is defined you can access it anywhere, not just in other member functions:
int get_m_n()
{
int k = a::m_n;
return k;
}