What do I declare with the following definition:
void (*bar)(A*){ }; //1
My first thought was that I declare and define function pointer and a function the pointer point to. But it's wrong, because any call to the bar() leads to a segmentation fault:
#include <iostream>
#include <vector>
#include <memory>
struct A{ };
void foo(A*){ std:cout << "foo" << std::endl; }
void (*bar)(){ };
int main(){
bar();
}
Moreover, I can't imbed any statement into the "definition":
void (*bar)(A*){ std::cout << "foo" << std::endl };
yeilds compile-time error.
So, what does the declaration //1 mean?
This statement:
void (*bar)(A*){ };
declares a variable named bar of type void(*)(A*), ie "pointer to function taking pointer to A and returning void", and zero-initializes it. Thus, it's equivalent to this:
void (*bar)(A*) = nullptr;
Obviously, when calling this bar, a segfault should be no surprise.
It's not possible to declare a function and a pointer to that function in a single declaration.
When you say
void (*bar)(A*){ }; //1
it means "bar" is a function pointer which can point to some function which takes "A*" as parameter.
In your case, it is not pointing to any function yet.
to make it working use,
void (*bar)(A*) = foo;
This means you have declared a function pointer that points to nothing at the moment. You should able to validate that using a debugger.
void (*bar)(A*){ }; //1
You could make the pointer point to a function like this:
void foo(A*){ std::cout << "foo" << std::endl };
bar = &foo;
And call it like this now:
A a;
bar(&a);
Full snippet:
#include <iostream>
class A {};
void (*bar)(A*){};
void foo(A*) { std::cout << " foo " << std::endl;}
int main() {
A a;
bar = &foo;
bar(&a);
}
Your code should be changed to the following code.
#include <iostream>
#include <vector>
#include <memory>
struct A{ };
void foo(A*){ std::cout << "foo" << std::endl; }
void (*bar)(A*);
int main(){
A a;
bar = &foo;
bar(&a);
}
To declare an actual function, get rid of the (*) portion around the function name:
void bar(A*){ std::cout << "foo" << std::endl };
https://ideone.com/UPIYxg
So, what does the declaration //1 mean?
It is just a comment.
Related
I could not understand the second foo call in the code below. How does it call global foo function. Why does (foo) call struct A's int()? Can you help me?
#include <stdio.h>
#include <utility>
#include <iostream>
using namespace std;
namespace MySpace{
struct A{
operator int () const {
cout <<"operator" << endl;
return 1;
}
};
void foo(A){
std::cout<< "1" << endl;
}
}
void foo(int){
std::cout << "--2" << endl;
}
int main()
{
MySpace::A x;
foo(x);
(foo)(x);
return 0;
}
I could not understand the second foo call. How does it call global foo function. Why does (foo) call struct A's int()? Can you help me?
The 1st one works because ADL finds MySpace::foo and it wins in overload resolution against ::foo and gets called.
For the 2nd one, adding parentheses like (foo) prevents ADL; then MySpace::foo can't be found, only ::foo is found and gets called. A is converted to int implicitly (by A's conversion operator) for it to be called.
BTW: You can mark the conversion operator as explicit to forbid the implicit conversion from A to int. Then the 2nd one would fail. E.g.
namespace MySpace {
struct A{
explicit operator int () const {
cout <<"operator" << endl;
return 1;
}
};
void foo(A){
std::cout<< "1" << endl;
}
}
Can I send an instance to a function not by using the . operator?
For example:
// header file
class A
{
public:
void foo() {std::cout << "Hello" << std::endl;}
};
// main file
A instance = new A;
instance.foo();
// instead do something like this
A::foo(instance);
Can I do something like that?
Yes, you can indirectly via std::invoke:
#include <functional>
#include <iostream>
struct A {
void foo() {
std::cerr << "hi\n";
}
};
int main() {
A a;
std::invoke(&A::foo,a);
}
But std::invoke's implementation will internally probably just apply the .* operator.
You're more than welcome to use the pointer to member syntax.
A instance;
auto fn = &A::foo;
(instance.*fn)();
.* is a different operator than .. Whether this is more readable is left as an exercise to the reader (hint: it's not)
I have broken down my issue into a small simple program.
I have a class myclass I have created in a separate .cpp file "classes.cpp" and declared in the header file "classes.h". myclass contains a variable a of which is initialized when instantiated. This makes variable a = 5.
My overall goal is to create a class in a separate .cpp file declared in a .h file which I can create multiple instances of in my main() program. The problem I am having is this.
In my main() function I create an instance of myclass called first.
my main program shows the variable a is set to the number 5.
If I want to change that number using a static function (and it has to be a static function as this relates to something much bigger in another program I am writing). I call the static function directly and in that static_function I create an instance of myclass and call the non_static_function because static functions have no implicit 'this' connecting them to an object.
In my non_static_function I change the value to the number 8. The problem is that the value of variable 'a' in 'first' remains at 5 when I want it to be 8. I need to change the value using first->static_function(8) and not by first->a = 8. . How can I do this?
Code below:
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "the actual value of a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass::myclass()
{
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
cout << "The value for variable 'a' was 5 but is now: " << a << endl;
}
void myclass::static_function(int x)
{
myclass *p = new myclass();
p->non_static_function(x);
}
If you want every instance of myclass to have its own a and you want to call a static function to change it then you need to pass the instance you want changed to the static function. A static function can only modify static members of a class or the members of an instance that is inside its scope. Non static member functions can change any variable that is a member of the class.
class Foo
{
private:
int bar;
public:
static void static_function(int value, Foo & foo) { foo.bar = value; }
void non_static_function(int value) { bar = value; }
};
int main()
{
Foo foo;
Foo::static_function(8, foo);
// now bar will have the value of 8
foo.non_static_function(20);
// now bar will have the value of 20
}
I have finally found a way to deal with this small problem. Above the 'myclass' definition in classes.cpp I declare a 'myclass' variable
myclass *tgt; . Then in my constructor for 'myclass' I just allocate the instantiated object to a my global myclass variable of which I can access from the myclass definition tgt = this; Now I can use tgt in my static function to call the non_static_function in my 'myclass' definition and it all works perfectly.
NathanOliver, you are correct in saying that I need a class instance but the way I have done it here suits my needs. Passing the instance of myclass is certainly another way of doing this but it would require a global function above my 'myclass' definition.
Thanks for the help.
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->non_static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "The actual value of a is still: " << first->a << endl;
myclass *second = new myclass();
cout << "For the 'second' class the variable a is: " << second->a << endl;
second->non_static_function(23);
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl;
cout << "And first->a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass *tgt; // *Add a global myclass variable above the myclass
definition*
myclass::myclass()
{
tgt = this; // *In the constructor allocate the instantiated class
//from main() to "tgt" .*
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
// Now see that the value of a is changed.
cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl;
}
void myclass::static_function(int x)
{
tgt->non_static_function(x);
}
The program:
#include <iostream>
void foo(void (*bar)()){ bar(); };
void foo(int a = 5)
{
std::cout << a << std::endl;
}
int main()
{
foo(foo); //Error
}
DEMO
I expected that eventually foo(5) will be called. In contrast, the following program works fine:
#include <iostream>
void foo(void (*bar)()){ bar(); };
void foo()
{
std::cout << 5 << std::endl;
}
int main()
{
foo(foo); //OK
}
DEMO
Could you explain that difference?
In the first example although foo has default argument its type is void (bar*)(int). Having the default argument makes it possible to call foo without specifying the argument value explicitly, but there is still an int argument. Simply its value is automatically populated(during compilation).
I am trying to do something I thought was simple: calling functions that call functions that call functions (from inherited classes) using a chain of pointers. Is there a better way of accomplishing this? Also, in the spirit of C++11, how would I incorporate smart pointers in this example? This example crashes the application:
Here is the sample code, apologies if it looks a little silly:
Actual output (Crashes!):
almost there...
Desired output:
almost there...
hello from function1
f1.h:
#ifndef FUNCTION_1_H
#define FUNCTION_1_H
//f1.h (header file)
#include <iostream>
struct f1{
int _a;
f1() {}
void function1();
};
#endif
f2.h:
#ifndef FUNCTION_2_H
#define FUNCTION_2_H
//f2.h (header file)
#include "f1.h"
struct f2 : public f1{
int _b;
f1* f1_ptr;
f2() :f1(){}
void function2();
};
#endif
f3.h:
#ifndef FUNCTION_3_H
#define FUNCTION_3_H
#include "f2.h"
struct f3 :public f2{
int _c;
f2* f2_ptr;
f3() : f2(){}
void function3();
};
#endif
CPPs:
f3.cpp:
#include "f3.h"
void f3::function3(){
//do stuff...
//e.g. calculate an int Var3
f2_ptr->function2(/*pass Var3 as argument*/);
}
f2.cpp:
#include "f2.h"
void f2::function2(/*receive Var3*/){
//do stuff with Var3
//e.g. maybe use Var3 to calculate an int Var2
std::cout << "almost there..." << std::endl;
f1_ptr->function1(/*pass Var2 as argument*/);
}
f1.cpp:
#include "f1.h"
void f1::function1(/*receive Var2*/){
//take Var2 and use elsewhere
//or continue linking to other functions
std::cout << "hello from function1" << std::endl;
}
main.cpp:
int main(){
f3* ptr3 = new f3;
ptr3->function3();
//delete ptr3;
std::cin.get();
return 0;
}
The problem is that in the upper classes, the pointers f2* and f1* are not initialized, so when you do f2_ptr->function2(), you are trying to access a member function via an uninitialized pointer, which leads to UB (undefined behaviour). Your code is doing basically this:
#include <iostream>
using namespace std;
struct Base
{
void f(){cout << "In f" << endl;}
};
struct Derived
{
Base* ptr;
};
int main()
{
Derived* foo;
foo->ptr->f(); //cannot use foo->ptr, it is not initialized
}
So you have to make sure that in the constructors of f3 you initialize the f2_ptr and so on. About smart pointers, you can use std::unique_ptr or std::shared_ptr, the syntax is std::unique_ptr<Foo> pointer( new Foo ) (and similarly for std::shared). It is highly recommended to use them, for example, you HAVE TO initialize them (cannot arrived at this problem if you'd have used smart pointers)
Here is a hint for how to write f3.cpp:
#include "f3.h"
// define the constructor here (and just declare it in the header `f3.h`)
f3::f3() : f2()
{
auto f2_ptr = std::make_shared<f2>();
// and all our nightmares are over, f2_ptr is now a valid pointer
// which will automatically release the allocated memory
// when the reference count is zero
}
void f3::function3()
{
//do stuff...
//e.g. calculate an int Var3
f2_ptr->function2(/*pass Var3 as argument*/);
}
And since I started this, here is a full C++11 example (it uses in-class initialization) with chaining and that uses smart pointers, which works and is basically equivalent to yours:
#include <iostream>
#include <memory>
using namespace std;
struct Base
{
void f_base()
{
cout << "In f_base" << endl;
}
};
struct Derived
{
void f_derived()
{
cout << "In f_derived" << endl;
}
std::shared_ptr<Base> ptrBase = make_shared<Base>();
};
struct DerivedDerived
{
std::shared_ptr<Derived> ptrDerived = make_shared<Derived>();
};
int main()
{
DerivedDerived *foo = new DerivedDerived;
foo->ptrDerived->ptrBase->f_base(); // OK now
}
PS: this may help you understand what's going on
When does invoking a member function on a null instance result in undefined behavior?