Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have called a pointer of member function from another class. This function has 2 arguments.
It is working... But in this member function, in the debugger, I see that values of arguments were swapped (mixed). I see the correct values but not in correct variables(arguments). May be it is BUG...
Qt Creator c++
void SmartCTL::OnReadBufferA(int shm_id, int length); //declaration
hookedIDs[HOOKIDPOINTERS::READBUFFERA] = (void *)&SmartCTL::OnReadBufferA; // Save pointer of function
memcpy(hookedIDs[smartCTL.shellID],smartCTL.hookedIDs,8*sizeof(void *));// copy pointers
void (*pf)(int,int )= (void(*)( int,int ))hookedIDs[i][HOOKIDPOINTERS::READBUFFERA];// set pointer
pf(shells[i]->readBuff.shm_id,shells[i]->readBuff.length); // call hear
In result I get value hells[i]->readBuff.shm_id in length and value shells[i]->readBuff.length in shm_id
This isn't a bug. What you have is undefined be behavior. A member function is not the same as a regular function. There is a this in the member function and the way it gets that is through an implicit function parameter of the class type. So
void SmartCTL::OnReadBufferA(int shm_id, int length)
is really something like
void SmartCTL::OnReadBufferA(SmartCTL& this_ref, int shm_id, int length)
And this is why you can't cast a pointer to a member function to a pointer to a regular function.
If you need to have both member functions and regular functions in your "array" then you are going to need a std::function. It uses type erasure to allow you to to store different types of function objects that have the same interface. For example you could have something like
std::vector<std::function<void(int, int)>> functions;
functions.push_back(some_regular_function);
functions.push_back([](int shm_id, int length){ SmartCTL s; return s(shm_id, length); });
Another option is to make the member function a static function. A static function does not have a instance of the class bound to it so you can treat it as a regular function.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Cant pass a const data type into a non const function. After setting the func to type const the error on
assigning a value in the function will understandably set of an error because its not mutable as its inside
a function of type const.
How can I pass a const varaiable into a non const function by reference, and allow contents of the function
to be modified?
error C2662: void CarFactory::set_values(Car &) cannot conver this pointer from const Car to Car &
// Tried this
//Car& newCarData = const_cast<Car&>(myCar);
const Car& myCar = volvo->GetBuild();
// Tried this
//Car& newCarData = const_cast<Car&>(myCar);
set_values(&myCar);
void CarFactory::set_values(const Car& myCar){
// do some assigning here for mutable variables declared in the header
}
Should be able to call this without the error and pass through the data to set_values(). And also modify non const variables set in the header.
If you want to modify the Car object in set_values you must pass it a non-const reference. But that means that your volvo->GetBuild() must return a non-const reference too.
Solution below, not great but works for this. Backdoor pointer if you will.
CarFactory* ptr = const_cast<CarFactory*>(this);
In the end, I apologise for not having a minimal working version of code in the question. Tried to explain it where if you know consts you might be able to bounce some ideas around. The comments mentioned did support this solution so thank you.
This question already has answers here:
About Pointers To Functions in function declarations
(4 answers)
Closed 7 years ago.
In some C++ 98 code (meaning no, using std::function is not an option), I found the following construct:
class someClass
{
public:
typedef void callback();
void setCallback(callback c)
{
mCallback = c;
}
void callCallback()
{
if (mCallback)
mCallback();
}
private:
callback *mCallback;
};
This confused me. I am used to passing callback functions as a function pointer, so I would expect setCallback to take (*callback)() as argument.
However, the above code seems to work, and compiles without any (related) warnings.
Could someone tell me what is happening here? Is my callback function implicitly passed as a function pointer? Is it a good idea to use this instead of function pointers?
The only thing I could find is that this construction results in "parameter-declaration-clause" ambiguity (C++ 98 8.3p7). Is this the only downside? Are there any benefits?
Similarly to arrays, parameters of function type declare, in fact, a pointer to that type.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I know how useful it is to declare variable as a reference or pointer in a function, but I just wonder why we declare it as a reference in the private section of a class.
example
class DoSomething
{
private : int& t_; // why not just 'int t;'
};
How about if we declare the variable without reference, and define the object of a class as a pointer or reference? Is this not good practice?
If you declare the variable as int, its value would be "divorced" from the variable from which it has been initialized. If you keep it a reference, the variable would be "tracking" the variable with which it has been initialized:
class demoRef {
int &r;
public:
demoRef(int& x) : r(x) {}
void show() {cout << r << endl;}
};
class demoCopy {
int r;
public:
demoCopy(int& x) : r(x) {}
void show() {cout << r << endl;}
};
int main() {
int x = 123;
demoRef dRef(x);
demoCopy dCopy(x);
dRef.show();
dCopy.show();
x = 456;
dRef.show();
dCopy.show();
return 0;
}
This code produces the output below:
123
123
456
123
Demo on ideone.
Note: this is only an illustration of what you can do with a reference to an int. It is not meant to imply that you should do something like this without being extra careful, because a hidden reference like this makes your code harder to read.
There are many reasons you might have a reference member. An example from the standard library is the back_insert_iterator, which keeps a reference (or a pointer) to a container in order to call that container's push_back function.
Note that with any class like this, which stores a reference or pointer to another object, you need to take the same care as you would with a raw reference or pointer. That is, you need to be wary of dangling references, and ensure that you don't use the reference past the lifetime of the referent.
When you store a reference to a variable in a class, the outcome of changing the variable is:
You can change the variable in a member function of DoSomething and have that change be visible outside the class.
You can change the variable outside DoSomething and have that change be visible inside DoSomething.
The key question is: Where is it useful?
I have often found it useful in a functor that is passed to some of the functions in the standard library.
#BenjaminLindley already gave you a very good example of that.
I have often found it useful in Factory Patterns when a concrete Product is created using the data stored in a concrete Factory but the data is too expensive to copy.
I have used it in classes that implement a functional interface. These classes hold references to other data when:
3.1. The class needs to access to the data but it is too expensive to copy the data.
3.2. It makes no sense to copy the data or copying is prohibited by design (such as std::ofstream).
3.3. The class needs to update the data and make it visible to the calling code.
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 9 years ago.
Improve this question
Under the hood, a C++ method of a class is like a C function whose first parameter is an instance of the class - or struct.
For example:
void Foo::Do();
would be equivalent to this declaration in C:
void Do(Foo* this);
Hence, using a member m_someMember from within a method is like using this->m_someMember from inside the C function.
After so many years of C/C++ programming experience, I just recently asked myself: What if I call a method from an instance pointer that is NULL???
My guess was: If the method refers to no member at all, when why would it crash?
So I did a quick test (on a Windows platform, with Visual C++ 2008):
class Foo
{
public:
Foo() {}
virtual ~Foo() {}
void Do();
};
void Foo::Do()
{
cout << "Calling 'Do' for " << this << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo foo;
foo.Do();
Foo* pNullFoo = 0;
pNullFoo->Do();
return 0;
}
Which gives an output like:
Calling 'Do' for 0038FE5C
Calling 'Do' for 00000000
This could be an hassle when doing post-mortem debugging of a crash over an instance pointer that is null. You might think that this method cannot be called if this is invalid.
On the other hand, if the method is declared virtual:
virtual void Foo::Do() { ... }
Then the line:
pNullFoo->Do();
will produce an page fault exception. Why? Because instances of a class with virtual methods have a pointer to the vtable to the child class virtual methods they belong to.
So the first thing the compiler would do is to make pNullFoo to access its vtable member, then bang!
In conclusion, this is better design to have non contextual functions like Do be implemented as procedural routines than methods, unless they are virtual.
Calling a member function on a NULL pointer invokes undefined behavior. Undefined doesn't mean it's going to crash, nor does it mean it's going to do the right thing - it's undefined. Anything could happen.
The only time I've seen this in production code is with Microsoft's CWnd::GetSafeHWND function. But since they wrote the compiler, they can get away with it.
The proper design for member functions that don't need to access any member data is to have them defined as static:
static void Do();
Then call it like:
Foo::Do();
And you don't even need to have an object or a pointer to do that.
This question already has answers here:
How to pass a method as parameter?
(2 answers)
Callback of member functions through 3d party library
(3 answers)
Closed 10 years ago.
I have some 3rd-part code:
class A(){
public:
void assingOnClickFunction(void (*function)();
};
I cannot change anything in that code.
I want to pass to that A::assingOnClickFunction() my method of class B, void B::someFunction(). I have tried (all inside of the B class!):
a->assingOnClickFunction(this->someFunction);
But I get the error:
function call missing argument list; use '&B::someFunction' to create
a pointer to member
So I have changed it to:
a->assingOnClickFunction(&B::someFunction);
But now there is ofc the error about the different types: (void(*)() and (&B::*)()
I cannot make B::someFunction() static (it uses a lot of non-static B's members and methods)!
So, is there an option to pass my B::someFunction() to the A::assingOnClickFunction(), not changing it to static and not changing anything in A class (A is not and cannot be aware of B, B includes A)?
If the member function you want to pass is not static, you cannot do that. The method in A accepts a function pointer to a function with no arguments, and a non-static member function has an implicit this pointer argument.
In order to call a (non-static) method of an object, you need to know both the object and the method to call.
The assingOnClickFunction() function only takes a pointer to a function, so you cannot pass it the needed information.
Besides some horrible hacks, like implementing a function that has access to some global instance of your object, and calls the method throught that, it can't be done.
A pointer to member function is not a pointer to function. If you have a function that takes an argument whose type is pointer-to-function, you cannot call it with a pointer to member function.