How to give an event handler access to member data? - c++

myWebClient->DownloadProgressChanged += gcnew DownloadProgressChangedEventHandler( &Form1::DownloadProgressCallback );
gives the error:
1>.\Form1.cpp(26) : error C3352: 'void Form1::DownloadProgressCallback(System::Object ^,System::Net::DownloadProgressChangedEventArgs ^)' : the specified function does not match the delegate type 'void (System::Object ^,System::Net::DownloadProgressChangedEventArgs ^)'
The documentation uses a static non member function as this delegate parameter, but I want to update a progress bar member of the Form1 class. What am I doing wrong here?
I am using .NET 2.0 so please keep the language as antiquidated as possible.

The delegate for a member function would be declared (within the form):
myWebClient->DownloadProgressChanged += gcnew DownloadProgressChangedEventHandler(this, &Form1::DownloadProgressCallback );
Basically, the first argument is the object one which the member function is defined. In this case, this should work.

Pass the object to the delegate constructor.
gcnew DownloadProgressChangedEventHandler( this, &Form1::DownloadProgressCallback );

Related

C++ error C2352: 'CSchedulerDlg::Select' : illegal call of non-static member function

I am attempting to modify and improve a job scheduler application in C++
Many of the member functions are declared as static, and hence cannot act on the non-static member variables.
The problem arises when attempting to add additional functionality to the class. In particular, I was wondering if it was possible to call a non-static member function inside the definition of a static member function.
That is, suppose we have the member functions declarations:
static void email(CString message);
CRecordset * Select(CString SQL, CDatabase* dataBase);
I would like to call the Selectfunction from within the implementation of the email function. But I get an error:
error C2352: 'CSchedulerDlg::Select' : illegal call of non-static member function
The error makes sense because static member functions cannot act upon the current object, but I still need to perform the Select function from within the email function. Does there exist a work around method?
The relevant code that causes the error is:
void CSchedulerDlg::email(CString message)
{
CRecordset * emails = Select("some SQL query", db);
}
where static CDatabase* dbis a private member variable within the class.
Why can you not simply provide an object for the Select function?
void CSchedulerDlg::email(CString message)
{
CSchedulerDlg aDlg; // Now you have an object.
CRecordset * emails = aDlg.Select("some SQL query", db); // This is now a valid call.
}
The only work around is to either make email non static, or add parameter CSchedulerDlg& to email:
static void email(CSchedulerDlg& dlg, CString message);
and call select on dlg object. Both solutions are quite similar.

function pointer is not a function or function pointer

I have following problem:
void MyClass::LoopFunction(vector<Item>& items,void (MyClass::*funcy)(vector<Item>&,int))
{
for(SInt32 i = 0; i < 50; i++)
{
funcy(items,i);
}
}
It says:
Called object type 'void(MyClass::*)(vector<Item>&,int)' is not a function or function pointer
Can anyone help me to find a solution for this?
funcy is a pointer to a member function, so you need to call it on an instance of the class, like this:
(this->*funcy)(items,i);
The thing with non-static member functions is that they have an invisible first argument which the compiler will turn into this inside the member function. This means that you can't call (non-static) member functions without having an object instance to call the member function on.
In your case, if you want to call it using the this objectinside LoopFunction you need to do e.g.
(this->*funcy)(items, i);
If you want to call it on another object instance, you need to pass that object to the function, and use that instead.
Or you could use e.g. std::function and std::bind instead of the member function pointer. Or use a template parameter similar to the way the standard library handles callbacks, and which allows you to pass any callable object to the function (still have to use std::bind if you want to use a non-static member function though).

Non static class used in another class <unresolved overloaded function type>

I'm struggling with using a non static function from one class inside another class. I've been reading some examples, but having a hard time understanding the basics of it. My best try so far, was by using the example given from http://www.newty.de/fpt/callback.html#static
I have two classes: ledStrips and MPTimers. MPTimers is a class to use timers on an Atmega. What I want, is to be able to call an instance of MPTimers within ledStrips. In the class of MPTimers, I can attach a callback function, which will be run each time the timer interrupts.
Here's an example of my code, only showing what's relevant.
MPTimers _timerOne;
// Constructor
ledStrips::ledStrips()
{
_timerOne.initialize(1000); // Set up timer with 1000 ms delay
_timerOne.attachFunction(timeout); // Attach a function to the timer
_timerOne.stop(); // Stop timer
}
The timeout function, which is the parameter in .attachFunction, is a member of ledStrips.
This is the code in MPTimers class
// AttachFunction
void MPTimers::attachFunction(void (*isr)() )
{
isrCallBack = isr;
}
And the error is:
error: no matching function for call to 'MPTimers::attachFunction(unresolved overloaded function type).
I know it's because my instance of MPTimers have no idea to know, which instance the callback function is referering to, because it's a non static member of the class.
I tried the solution as described in the link, but with no succes. Hope that some of you can help me to figure this out :).
If you want to use a functer on a non-static member function, the syntax would be
void MPTimers::attachFunction(void (MPTimers::*isr)() )
{
isrCallBack = isr;
}
and if you want to call it later the syntax would be
{
[....]
this->*isrCallback()
[....]
}
You can't call a non-static method of a class without an object instanced from that class. MPTimers::attachFunction expects a static method or function. If your timeout function is a normal C function then there should be no problem (so it's obviously not the case), if it is a static method of a class then you should use ClassName::timeout, if it's a non-static method of a class then you can't do what you want, you'll need to modify your attachFunction and your MPTimers class to accept functors or object/method pairs (or use a static timeout method).

compilation error C++ : can not call member function without object

I have the following main file where I tried to create a map with predefined value and pass it for further processing by other method. The main file is as is shown below :
int main(){
map<id,Porto> _portoInit;
id = 1;
Porto p;
p.val = 5;
_portoInit.insert(pair<id, Porto>(id, p));
Porto::setPorto(_portoInit);
return 1;
}
where the setPorto is defined under a class as the following (in seperate file)
void Porto::setPorto( const map<id,Porto>& _portoblock ) {
//do stuffs
};
I got prompted with an error of "error: cannot call member function ... without object"
Did not I declare the object of _portoInit in the main file already or it is a wrong way of declaration?
You need to invoke the method through the actual object:
p.setPorto(_portoInit);
Unless setPorto is a static method, your code is invalid.
You should write
p.setPorto(_portoInit);
The "::" defines the scope of the function and is implicit in the above, as the object who's function is being called is a Porto.
setPorto is a non-static member function, so you need to call it on a Porto instance. For example:
p.setPorto(_portoInit);
Note that non-static member functions take an implicit first parameter of (possibly cv qualified) type T*, so you could have called it like this:
Porto::setPorto(&p, _portoInit);
In both cases, you need an object to call the member function on. This is what the compiler is telling you.

QtConcurrent with member function

I create a QFuture that I want to use to parallelize calls to a member function. More precisely, I have a class solveParallel with .h :
class solverParallel {
public:
solverParallelData(Manager* mgr_);
virtual ~solverParallel(void);
void runCompute(solveModel * model_);
bool resultComput();
private:
Manager *myMgr;
QFuture<bool> myFutureCompute;
};
where the methode runCompute() is creating the myFutureCompute member. .cpp looks like
solveParallel::solveParallel(Manager* mgr_)
:m_mgr(mgr_)
{
}
solverParallel::~solverParallel(void){}
void solverParallel::runCompute(solveModel* model)
{
futureComput = QtConcurrent::run(&this->myMgr,&Manager::compute(model));
}
bool solverParallelData::resultComput()
{
return m_futureComput.result();
}
Include(s) are all right. Compilation fails, on line
futureComput = QtConcurrent::run(&this->myMgr,&Manager::compute(model));
with this error:
Error 44 error C2784: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1),const Arg1 &)' : could not deduce template argument for 'T (__cdecl *) (Param1)' from 'Manager **' solverparallel.cpp 31
In addition, on mouse info for '&Manager' in same line of code stands: Error: a nonstatic member reference must be relative to a specific object.
Do you see where is the trick? Thanks and regards.
From the official documentation :
QtConcurrent::run() also accepts pointers to member functions. The
first argument must be either a const reference or a pointer to an
instance of the class. Passing by const reference is useful when
calling const member functions; passing by pointer is useful for
calling non-const member functions that modify the instance.
You are passing a pointer to a pointer. Also notice that you cannot pass the arguments the way you do, but as extra arguments in the run function. The following should work:
futureComput = QtConcurrent::run(this->myMgr,&Manager::compute, model);