C++ static null pointer - c++

I can't figure out the following situation:
I've 3 classes:
AA.h
class AA
{
public:
AA();
static CC *i;
};
BB.h
class BB
{
public:
BB();
void static setI(CC *i);
};
CC.h
class CC
{
public:
CC();
};
AA.cpp
AA::AA(){}
CC *AA::i= nullptr;
BB.cpp
BB::BB(){}
void BB::setI(CC *i)
{
i = new CC();
cout<<i<<endl;
cout<<AA::i;
}
CC.cpp
CC::CC(){}
So I've a static pointe of type CC in the class A.
And i start the main in the following way:
int main(int argc, char *argv[])
{
BB::setI(AA::i);
return 0;
}
The output I get is
//0xaeed70
//0
So why AA::i does not equal i?

The parameter type of BB::setI is CC *i, the pointer itself is passed by value, i is copied from the argument. Any modification on i inside the function has nothing to do with the original argument AA::i.
What you want might be pass-by-reference, i.e.
void BB::setI(CC *&i)
{
i = new CC();
cout<<i<<endl;
cout<<AA::i;
}

In the expression i = new CC() variable i is local variable of function BB::setI which was initialized with the value of AA::i because you called function like BB::setI(AA::i);. Assigning any value to i will only change the value of this local variable, not the value of some other variable that has been used to initialize it when you called the function.

It's exactly the same situation as this smaller example:
int i = 0;
void setI(int x)
{
x = 1234;
cout << x << endl;
cout << i;
}
int main()
{
setI(i);
}
As you can see more clearly here, you're assigning a new value to the function's parameter.
This parameter is unrelated to AA's member.
Regardless of its type, if you want a function to modify an object, you need to pass it a reference (or pointer) to that object; you can't pass the object's value.

Related

How to queue up methods to run until a limit is reached

So I have a bunch of objects (subclasses of a parent class) with various functions each having different names, I might not have the resources to run all of the functions for each object so I want to have them in a priority list to run over time.
The code bellow is I believe forbidden by c++.
I get "C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function"
class A;
class Token;
list<Token> tokenList;
class Token{
public:
A* a; //Could be A or a child of A
int* function;
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello;
tokenList.push_back(token);
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
The code bellow should work but doesn't look elegant and also doesn't support subclasses having multiple functions they could pass to the list, is there a better way to do this I am missing?
class A;
list<A*> aList;
class A {
public:
virtual int funct();
};
class B : public A{
public:
virtual int funct(){
hello();
return 0;
}
int hello(){
cout << "hello" << endl;
return 0;
}
};
int main(){
//remove objects from list and run their functions in a loop until list is empty or max number of functions were run
Thanks Ted
Solution: Using the first example as mentioned I changed int* function; to int (A::*function)();. Then I can run the function with something like this
A tmp = A();
Token token = *tokenList.begin();
A *a = token.a;
(a->*token.function)();
}
The problem is that in your code int* function; is a pointer to an integer and not a pointer to a function.
If you would define it as int (*function)(); you could easily do what you want. But it would still not work with member functions.
So you need to define it as a pointer to a member function: int (A::*function)();
Here an example to make it work:
class Token{
public:
A* a; //Could be A or a child of A
int (A::*function)(); // pointer to member function with no arg, returning int
};
class A {
public:
A() {
Token token = Token();
token.a = this;
token.function = &A::hello; // Use the address of member function
tokenList.push_back(token);
}
int hello(){
cout << "hello (" << this <<")"<< endl; // added the address of a to see for which object
return 0;
}
};
int main() {
A a;
A b;
for (auto& token : tokenList )
(token.a->*token.function)(); // invoke the member function on the object pointer
}
Online demo
I didn't notice that your tokenList was a global variable. This is rather risky, as everything you create an A (including a temporary one), the tokenList will be updated. When you'll execute it, you'll therefore risk of having dangling pointers, i.e. pointing to an A instance that has already destroyed.

vector of call back functions and function pointer binding

I am new to the std::function and trying to implement a callback function. In the following code "Callback_t" contains a function that holds a vector of function to be called. Class "other" is a nested class inside "SomeClass". An object of "SomeClass" contains an array of nested class object "b". The "other" class constructor assigns a function pointer to "fptr". I push this function in to the vector of callback class "Callback_t". When I run this code, I get the segmentation fault when the first function in the vector is invoked. I am not able to figure out what is wrong with the statement
this->loc_ptr->set_of_cb.push_back(this->b[i].fptr);
However if I replace it with
this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))
the code works perfectly. I need help to understand what's wrong with the original statement.
#include <functional>
#include <iostream>
#include <vector>
typedef std::function<void(void)> func_type;
class Callback_t {
public:
std::vector<func_type> set_of_cb;
void myCallback()
{
for (int i = 0; i < set_of_cb.size(); i ++){
set_of_cb[i]();
}
}
};
class SomeClass;
class SomeClass {
private:
Callback_t *loc_ptr;
int a[10];
class other{
public:
int id;
SomeClass *loc;
func_type fptr;
other(){};
other(SomeClass *loc, int id){
this->id = id;
this->loc =loc;
fptr = std::bind(&other::func,this);
}
void func(void){
this->loc->a[id] = loc->a[id] * id;
return;
}
};
public:
other *b;
//other b[10];
SomeClass(Callback_t *a = nullptr){
this->loc_ptr = a;
this->b = new other[10];
for(int i =0; i <10;i++){
this->a[i] = i;
this->b[i] = other(this, i);
this->loc_ptr->set_of_cb.push_back(this->b[i].fptr);
}
}
void read(void){
for(int i =0; i <10;i++){
std::cout<<a[i]<<std::endl;
}
}
};
int main()
{
Callback_t *tmp;
tmp = new Callback_t;
SomeClass tmp1(tmp);
tmp1.read();
tmp->myCallback();
tmp1.read();
delete tmp;
}
other(SomeClass *loc, int id){
this->id = id;
this->loc =loc;
fptr = std::bind(&other::func,this);
}
The constructor binds fptr to this, which is the constructed object. Now, pay careful attention:
this->b[i] = other(this, i);
This performs the following sequence of events. There are quite a few things happening here, that are crucial to this mystery:
A temporary other object gets constructed, and its constructor does what it does. Note that the object is temporary, so its constructor ends up binding its fptr to a temporary object! You're beginning to see the problem, but let's close the loop, anyway:
The object gets assigned to this->b[i]. This is effectively a copy.
The original temporary objects gets destroyed.
The end result is that b[i]'s bound function ends up getting bound to a temporary object that is now destroyed. This results in undefined behavior and your crash.
And with your working alternative:
this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))
You are binding the std::function to a valid instance of the object, in b[i].
That's it.
The other answer explains what is going wrong in your code. What is left to do is to show case a more canonical example of achieving what you go for (with a little help from lambda functions). Of course, std::bind() also works, but it is pre C++11 and I think nowadays most would rather do it as I do in my code below.
#include <iostream>
#include <functional>
#include <vector>
class Foo {
public:
void FooFun() {
std::cout << "Foo::FooFun() called" << std::endl;
}
};
class Bar {
public:
void BarFun() {
std::cout << "Bar::BarFun() called" << std::endl;
}
};
using CallbackFun_t = std::function<void()>;
using Callbacks_t = std::vector<CallbackFun_t>;
int main(int argc, const char * argv[]) {
Foo foo{};
Bar bar{};
Callbacks_t callbacks
{ [&foo]{ foo.FooFun();}
, [&bar]{ bar.BarFun();}
};
for( auto& cb : callbacks ) {
cb();
}
return 0;
}

Why this code showing an error lvalue required in line 1? How to resolve it?

#include<iostream>
using namespace std;
class Test
{
private:
int x;
public:
Test(int x = 0) { this->x = x; }
void change(Test *t)
{
this = t; //line 1
}
void print() { cout << "x = " << x << endl; }
};
int main()
{
Test obj(5);
Test *ptr = new Test (10);
obj.change(ptr);
obj.print();
return 0;
}
since we know that this pointer hold the reference of calling object. In line 1 i am trying to change the reference of calling object but it shows an error "lvalue required". Can someone explain this??
You cannot assign a pointer to this pointer, because it's a prvalue.
this pointer is a constant pointer that holds the memory address of the current object.
As a result, this is of type const Test* in your case, so it cannot be assigned to. Doing so (if it was allowed) would effectively allow an object to change its own address in memory, as #Peter mentioned.
Note: const Test* is a pointer to a constant object. The object it points to is constant, not the pointer itself.
PS: this->x = t->x; is probably what you meant to say.
Here you are assigning a pointer(here t) to "this" pointer for a particular object.
"this" pointer is const. pointer that holds the memory address of the current object. You simply can't change the this pointer for an object, since doing this you will practically be changing the location of the object in the memory keeping the name same.
Reference - ‘this’ pointer in C++
#include <iostream>
using namespace std;
class Test
{
private:
int x;
public:
Test(int x=0)
{
this->x = x;
}
void change(Test *t)
{
t->x; //t is a pointer. so make it point to x
}
void print() { cout << "x = " << x << endl; }
};
int main()
{
Test obj(5);
Test obj1(10); //create a new object
Test *ptr = &obj1;//make the pointer point to obj1
obj.change(ptr); //use change() to point to argument of obj1
obj.print(); //print the value of obj now
return 0;
}

Convert object function to function pointer

I'm trying convert a object function to function pointer but can't get it, i've done something like this, simple example:
typedef struct
{
int v1;
int DoSome(int a)
{
return v1 * a;
}
} strx;
int main()
{
strx a; // instance...
a.v1 = 2;
std::function<int(strx* instance, int value)> DoSome = std::mem_fn(&strx::DoSome);
cout << DoSome(&a, 4) << endl; // 16 ok
int(*pDoSome)(strx* instance, int value) = (int(*)(strx*, int))std::mem_fn(&strx::DoSome); // syntax error
// ptr method...
pDoSome(&a ,4);
return 0;
}
and i have obtained something like:
main.cpp [Error] invalid cast from type 'std::_Mem_fn' to type 'int ()(strx, int)'
How i can do correctly the casting?
You can't. This is why std::function is more flexible than pointers to functions.
How i can do correctly the casting?
You cannot. Object pointers and function pointers are totally different concepts. Only nullptr can be used to initialize both types of pointers. Otherwise, they are not guaranteed to be compatible.
I suggest sticking with the std::function.
If you must have a function pointer, you have to use a non-member function or a static member function of a class.
E.g.
int doSomeFunction(strx* instance, int value)
{
// Use instance any way you please.
// ...
//
return 0;
}
int main()
{
strx a; // instance...
a.v1 = 2;
int(*pDoSome)(strx* instance, int value) = doSomeFunction;
// ptr method...
pDoSome(&a ,4);
return 0;
}

Using pointers in class over multiple functions C++

So I have 2 functions and 1 class.
with 1 function I want to Set value's of the integers stored in a class.
with the other function I want to use these value's again.
I'm using pointers as I thought this would be saved on Memory address's across the whole program.
#include <iostream>
using namespace std;
void Function1();
void Function2();
class TestClass
{
public:
TestClass();
~TestClass();
void SetValue(int localValue)
{
*value = localvalue;
}
int GetValue()const
{
return *value;
}
private:
*value;
};
TestClass::TestClass()
{
value = new int(0);
}
TestClass:
~TestClass()
{
delete value;
}
int main()
{
TestClass *tommy = new TestClass; //this didn't work,
//couldn't use SetValue or Getvalue in functions
Function1();
Function2();
return 0;
}
void Function1()
{
int randomvalue = 2;
TestClass *tommy = new TestClass; //because it didnt work in main, i've put it here
tommy->SetValue(randomvalue);
}
void Function2()
{
TestClass *tommy = new TestClass;
cout << tommy->GetValue();
<< endl; //this gave a error, so I put the above in again
//but this returns 0, so the value isn't changed
}
So, got a solution for me? I didn't got any compile errors, but the value isn't changed, probably because the destructor is called after Function1 has been completed. so how do I do it?
You need to pass your tommy from main() to each of your functions, not create a new one in each time, otherwise you're just losing the new Testclass objects you're creating in your functions, and actually here getting memory leaks because you use new.
Something like:
void Function1(TestClass * tommy) {
int randomvalue =2;
tommy->SetValue(randomvalue);
}
and then in main():
int main() {
TestClass *tommy = new TestClass;
Function1(tommy);
std::cout << tommy->GetValue() << std::endl; // Outputs 2
delete tommy;
return 0;
}
This is an odd use case, though - this would be the kind of thing you'd expect member functions to do. This would be better:
int main() {
TestClass *tommy = new TestClass;
tommy->SetValue(2);
std::cout << tommy->GetValue() << std::endl; // Outputs 2
delete tommy;
return 0;
}
without the need for Function1() and Function2(). Either way, you're going to have to fix:
private:
*value;
in your class, as someone else pointed out.
you are not passing your TestClass to either function so they functions can't see the tommy object you made. Then in each function you create a new local variable that just happens to have the same name as your local variable in main... They are all independent objects
Every time you write new TestClass, you are quite literally creating a new instance of a TestClass object. The new instance is not related to any existing instances in any way, except for being of the same type. To make the single instance of TestClass be "the one" being used by your functions, you need to pass it in as an argument to those functions.
Also -- Don't use pointers unless it is absolutely necessary.
Here's a cleaned up example of your code that accomplishes what it appears you were trying.
class TestClass
{
int value;
public:
TestClass() : value(0)
{}
int GetValue() const { return value; }
void SetValue(int x) { value = x; }
};
// takes a "reference", works somewhat like a pointer but with
// some additional safety guarantees (most likely will not be null)
// This will modify the original passed in TestClass instance.
void SetRandomValue(TestClass& tc)
{
int random = 2; // not really random...
tc.SetValue(random);
}
// take a const reference, similar to above comment, but a const
// reference cannot be modified in this scope
void Print(const TestClass& tc)
{
std::cout << tc.GetValue() << "\n";
}
int main()
{
// create a TestClass instance with automatic storage duration
// no need to use a pointer, or dynamic allocation
TestClass tc;
// Modify the instance (using reference)
SetRandomValue(tc);
// print the instance (using const reference)
Print(tc);
return 0;
}