Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How would one go about calling a function by pointer without using the ampersand in the function call where I pass in a struct. I can only edit the function definition, not the way the function is being called. Call by reference can be used, but I would like to call by pointer, is there any way of doing this?
void Some_Func(struct TheStruct &My_struct){
My_struct->member = 4; // Would like to do this!
}
int main(){
Some_Func(My_Struct);
}
To be honest, I think this question was triggered by some misunderstanding....Lets assume you have this (working) code:
struct TheStruct { int member;};
void Some_Func(struct TheStruct &My_struct){
// some implementation
}
int main(){
TheStruct x;
Some_Func(x);
}
You say
I can only edit the function definition, not the way the function is being called.
...thus there is no way to make the function take a pointer as parameter. If there is a instance (not a pointer) passed as parameter in main and you are not allowed to change main, then you cannot magically make the parameter a pointer.
The only way to use -> inside the function is
void Some_Func(struct TheStruct &My_struct){
TheStruct* x = &MyStruct;
x->member = 4;
}
However, there is not a single reason to do so (unless the . on your keyboard is broken) and it makes the code confusing to read.
I am 90% sure this is not the answer you are looking for, but I'll post it for the remaining 10% of doubt anyway:
Have a look at std::addressof(T&). It gives you the pointer without using an ampersand.
When accessing an object by reference, you have to use the . operator to reach its members:
void Some_Func(TheStruct &My_struct) {
My_struct.member = 4;
}
int main() {
TheStruct My_struct;
Some_Func(My_Struct);
// or:
// TheStruct *My_struct = new My_struct;
// Some_Func(*My_Struct);
// delete My_struct;
}
When accessing an object by pointer, you have to use the -> or *. operator to reach its members:
void Some_Func(TheStruct *My_struct) {
My_struct->member = 4;
// or (*My_struct).member = 4;
}
int main() {
TheStruct My_struct;
Some_Func(&My_Struct);
// or:
// TheStruct *My_struct = new TheStruct;
// Some_Func(My_Struct);
// delete My_struct;
}
If you don't want to use the & operator to get the address of an object variable (maybe because it overrides operator&, for instance), you can use std::addressof() in C++11 and later:
int main() {
TheStruct My_struct;
Some_Func(std::addressof(My_Struct));
}
Or use boost::addressof:
#include <boost/utility.hpp>
int main() {
TheStruct My_struct;
Some_Func(boost::addressof(My_Struct));
}
Or implement addressof() manually:
template<class T>
T* my_addressof(T& arg)
{
return reinterpret_cast<T*>(
&const_cast<char&>(
reinterpret_cast<const volatile char&>(arg)
)
);
}
int main() {
TheStruct My_struct;
Some_Func(my_addressof(My_Struct));
}
This will work.
struct TheStruct {
int member;
};
void Some_Func(TheStruct &My_struct){
My_struct.member = 4;
}
int main(){
TheStruct My_Struct;
My_Struct.member = 5;
std::cout << My_Struct.member << std::endl;
Some_Func(My_Struct);
std::cout << My_Struct.member << std::endl;
return 0;
}
Output:
5
4
Related
I need to save in Arrays method pointers, something like this:
int main() {
void* man[10];
man[0]= void* hello();
man[0](2);
}
void hello(int val){
}
The question is, i can do that?
Thanks
Yes, you can easily achieve this by creating an array of function pointers. This is most readable if you alias the function type first:
void hello(int);
void world(int);
int main()
{
using fn = void(int);
fn * arr[] = { hello, world };
}
Usage:
fn[0](10);
fn[1](20);
Without a separate alias the syntax is a little hairer:
void (*arr[])(int) = { hello, world };
Or:
void (*arr[2])(int);
arr[0] = hello;
arr[1] = world;
Yes you can, but may I recommend std::function? It handles more complex cases, such as pointers to class methods, much more easily.
Here's an example of both the function pointer way and the std::function way:
#include <iostream>
#include <functional> // for std::function
//typedef void (*funcp)(int); // define a type. This makes everything else way, way easier.
//The above is obsolete syntax.
using funcp = void(*)(int); // Welcome to 2011, monkeyboy. You're five years late
void hello(int val) // put the function up ahead of the usage so main can see it.
{
std::cout << val << std::endl;
}
int main()
{
funcp man[10];
man[0]= hello;
man[0](2);
std::function<void(int)> man2[10]; // no need for typdef. Template takes care of it
man2[0] = hello;
man2[0](3);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm building an engine. I need to create a Timer class which will call a function by a pointer from a separate class. For example:
class MyTimer {
public:
void setTimeoutFunction( _pointer_, unsigned short timeoutMs ) {
// here we need to have a opportunity to store a _pointer_ to a function
}
void tickTimer() {
...
// here I need to call a function by a pointer
...
}
};
// Main class:
class MyAnyClass {
public:
void start() {
MyTimer myTimer;
myTimer.setTimeoutFunction( startThisFunc, 1500 ); // 1500ms = 1.5s
while ( true ) {
myTimer.tickTimer();
}
}
void startThisFunc() { ... }
}
In summation, how do you store a pointer to a function which belongs to some class and call that function by a pointer?
For your requirements, I might recommend making the timer a class template:
template <typename T>
struct MyTimer
{
using FuncPtr = void (T::*)();
MyTimer(FuncPtr ptr, T * obj, unsigned int timeout_ms)
: ptr_(ptr), obj_(obj), timeout_ms_(timeout_ms) {}
void tickTimer()
{
(obj_->*ptr_)();
}
FuncPtr ptr_;
T * obj_;
unsigned int timeout_ms_;
};
Usage:
struct MyAnyClass
{
void start()
{
MyTimer<MyAnyClass> myTimer(&MyAnyClass::startThisFunc, this, 1500);
while (true) { myTimer.tickTimer(); }
}
void startThisFunc() { /* ... */ }
};
In C++11 you can use std::function. A good guide on using it is here: http://en.cppreference.com/w/cpp/utility/functional/function
I created a new code snippet only containing the case you want.
#include <stdio.h>
#include <functional>
#include <iostream>
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
};
int main()
{
// store a call to a member function
std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
const Foo foo(314159);
f_add_display(foo, 1);
return 0;
}
I run in to segmentation faults when running this code (no compiler warnings or errors).
It occurs when trying to assign "Test" to str->sString
MyClass.cpp
//Constructor
MyClass::MyClass( MyStruct *pDesc )
{
pDesc = new MyStruct();
//This is where I get a segmentation fault
pDesc->bar= 0xFF;
}
MyClass.hpp
class ClGadgetFs
{
public:
struct MyStruct{
int bar;
};
MyClass(MyStruct *pDesc = NULL);
};
I thought when calling new I would be aalocating memory for the struct? Like malloc(sizeof(myStruct))
Where am I wrong?
void setStruct(myStruct *str)
{
str->sString = "Test";
str->nNo = 4;
}
int main()
{
myStruct p;
setStruct(&p);
return 0;
}
you can do this instead
Edit
int main()
{
MyStruct *pDesc;
MyClass myClassInstance( pDesc );
std::cout<< pDesc->bar << std::endl;
return 0;
}
and
MyClass::MyClass( MyStruct *pDesc )
should be changed to
MyClass::MyClass( MyStruct *& pDesc )
void setStruct(myStruct*& str)
The above is probably what you want: changing the passed pointer, as output parameter.
#include <string>
struct myStruct
{
std::string sString;
int nNo;
};
void setStruct(myStruct **str)
{
*str = new myStruct();
(*str)->sString = "Test";
(*str)->nNo = 4;
}
int main()
{
myStruct *p;
setStruct(&p);
}
should be what you want, this is the C-style of passing the pointer; since you're allocating memory for the passed pointer, passing the pointer alone doesn't work, you should pass the pointer's address. Another way would be a reference to the pointer that Joop Eggen's answer points out.
str in the function setStruct is a local variable, whose life time is limited in this function.
So when new returns the address, there is no effect on the actual parameter. It is just the same to
void func(int a){
a = 4
}
You should use pointer to pointer or reference
void setStruct(myStruct ** str){
(*str) = new myStruct();
(*str)->sString = "Test";
(*str)->nNo = 4;
}
void setStruct(myStruct *& str){
str = new myStruct();
str->sString = "Test";
str->nNo = 4;
}
You should use a reference to your pointer to modify it in your function:
struct myStruct{
std::string sStrnig;
int nNo;
};
void setStruct(myStruct* &str){
str = new myStruct();
str->sString = "Test";
str->nNo = 4;
}
main(){
struct myStruct *str = 0;
setStruct( str );
}
It's likely that the caller of setStruct is allocating a myStruct on the stack:
myStruct value;
and you are calling setStruct(&value);
That would cause the segmentation fault as you would be attempting to rearrange the stack memory.
It's difficult to say anything else without the complete example though.
There's nothing wrong with the code as it stands aside from the fact that the value of the pointer following str = new myStruct(); is not passed back to the caller: the caller would be still referring to the pointer pointing to unallocated memory which would result in undefined behaviour. But that is not causing your crash since given where you say the error happens.
A simple fix would be to change the function prototype to
void setStruct(myStruct*& str)
i.e. pass the pointer by reference so the caller get's the modified pointer value back.
I'm trying to modify some variables [not necessary from the same class/struct] from keyboard's shortcuts, something like that:
A foo struct containing variables:
struct Foo {
int a;
float b;
};
struct Foo2 {
int c;
};
And a main like:
int main() {
Foo f;
Foo2 f2
void* p = &(f.a); //it could be &(f2.c)
if ('A' key activated) {
*p += 1;
}
}
Currently, I'm stucked at this point:
error: invalid operands to binary expression ('void' and 'int')
The only way to make it work is to change:
*p += 1;
By:
*(int*)p += 1;
Which is not a good solution, because I should not know the type pointed by p. Is there a way to do that?
Converting the pointer to void* lost the type information and the compiler will not know how to increment. Why don't you make a pointer to Foo instead?
int main() {
Foo f;
Foo* p = &f;
if ('A' key activated) {
p->a += 1;
}
}
Also keep in mind that incrementing a float is not a good idea!
For the quesion in the comment of this answer:
struct FooBar
{
int *a;
float *b;
};
int main() {
Foo f;
Bar b;
FooBar fb{&f.a, &b.b};
if ('A' key activated) {
*(fb.a) += 1;
}
}
Note that this solution is rather C-style. Look at lethal-guitar's answer for a more C++-style solution.
Edit: At first I didn't realize that you want to have different types per entry. Based on the task of handling keyboard shortcuts, you could use a polymorphic class, and put instances of it into a std::map:
class KeyHandler {
public:
virtual void onKeyStroke() = 0;
};
class MyHandler : public KeyHandler {
public:
MyHandler(int& value) : myValue(value) {}
virtual void onKeyStroke() {
myValue_ += 1;
}
private:
int& myValue_; // Other subclasses could have other data
};
// Now place instances of different Handlers into a std::map
typedef std::shared_ptr<KeyHandler> PKeyHandler;
std::map<char, PKeyHandler> bindings;
bindings['A'] = PKeyHandler(new IncrementIntHandler(&someInt));
bindings['B'] = PKeyHandler(new IncrementFloatHandler(&someFloat));
// The actual input handler then just invokes
// the correct handler for a key stroke.
bindings[keyCode]->onKeyStroke();
That way, you can define a handler class for every action you want to support, and implement the corresponding logic into these classes. You could make the base class' implementation just do nothing to handle non-mapped keys, etc.
Sure, use an int pointer instead:
int * p = &f.a;
if ( /* condition */ ) { ++*p; }
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.