I'm using a library which requires me to derive from a class it provides and then override a function.
However, I'm facing a strange situation where changes made within the member function are:
Temporary: they last only in the scope of the member function.
Non-persistent: In an iteration, the changes made in previous iterations are not visible.
For example, if I have a global int variable initialized to 0 which I increment in the member function, it's value pre-increment is 0 and 1 post-increment while within the member function, but always 0 outside the function's scope. Here is an example that demonstrates the problem:
#include <iostream>
#include <thread>
#include <gtkmm.h>
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
#include <xmlrpc-c/server_abyss.hpp>
class TestWindow : public Gtk::Window {
public:
TestWindow();
// Called from worker thread
void notify(void (*callback)());
//Dispatcher handler
void on_notification_from_worker_thread();
//Data
Glib::Dispatcher m_Dispatcher;
//Callback functions
void (*on_notify_callback)();
};
class RpcWorker {
public:
RpcWorker(TestWindow* nw);
TestWindow* window;
RpcWorker* worker;
void start_thread ();
};
RpcWorker::RpcWorker(TestWindow* nw){
window = nw;
}
void foo (){
std::cout << "Foo called" << std::endl;
}
void bar (){
std::cout << "Bar called" << std::endl;
}
class testFunction : public xmlrpc_c::method {
public:
testFunction(TestWindow* nw, RpcWorker* worker);
TestWindow* window;
RpcWorker* worker;
void execute(xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP) {
window->notify(bar);
*retvalP = xmlrpc_c::value_int(0);
}
};
testFunction::testFunction(TestWindow* nw, RpcWorker* wk){
window = nw;
worker = wk;
}
void RpcWorker::start_thread() {
std::cout << "Thread started" << std::endl;
xmlrpc_c::registry myRegistry;
xmlrpc_c::methodPtr const testFunctionP(new testFunction(window, this));
myRegistry.addMethod("next.hideMinibuffer", testFunctionP);
xmlrpc_c::serverAbyss myAbyssServer (myRegistry, 8080, "/tmp/xmlrpc_log");
myAbyssServer.run();
}
TestWindow::TestWindow(){
m_Dispatcher.connect(sigc::mem_fun
(*this, &TestWindow::on_notification_from_worker_thread));
on_notify_callback = foo;
}
void TestWindow::notify(void (*callback)()) {
on_notify_callback = callback;
m_Dispatcher.emit();
}
void TestWindow::on_notification_from_worker_thread() {
on_notify_callback();
}
int main(int argc, char *argv[]){
auto app = Gtk::Application::create(argc, argv, "Test.Window");
TestWindow window;
RpcWorker worker = RpcWorker(&window);
std::thread* rpc_worker_thread = new std::thread(&RpcWorker::start_thread, &worker);
return app->run(window);
}
In this example, the on_notify_callback variable in the TestWindow class is initially set to point to function foo but later changed to function bar. Calling the function through the pointer while within the execute method immediately after changing it, function bar is invoked. However, once outside the scope of method execute, on_notify_callback points to foo.
What is causing this situation, and how do I fix it or work around it?
Related
I'm trying to create a dummy function inside of a class, whichs' body will be changed later in int main(). And then I'd like to call this body changed func in the class. Is there a way to achieve this?
Something like this:
class Animation {
public:
//Don't know what to write at the next line
function<void>/*?*/ whenCompleted = []() mutable { /* Dummy func. */ };
.
.
.
void startAnimation() { /* Do stuff, then */ animationEnded(); }
void animationEnded() { whenCompleted(); }
}score;
int main(){
score.whenCompleted = { /* new body for whenCompleted() */ }
score.startAnimation();
}
You basically have the right idea
#include <functional>
#include <iostream>
class Animation
{
public:
std::function<void()> whenCompleted;
void startAnimation() { animationEnded(); }
void animationEnded() { whenCompleted(); }
};
int main()
{
Animation score;
score.whenCompleted = [](){ std::cout << "all done"; };
score.startAnimation();
}
Will output
all done
You could also add a constructor for Animation that accepts a function to initialize whenCompleted with
Animation(std::function<void()>&& onCompleted) : whenCompleted(onCompleted) {}
which would modify main to
int main()
{
Animation score{[](){ std::cout << "all done"; }};
score.startAnimation();
}
There is a class "Mario". This one has an virtual method: void mission(). I want override this method and run it from base class code in parallel.
But output of the following code is:
Mario works hard
LOL
Code:
#include <iostream>
#include <thread>
class Mario
{
std::thread workingField;
bool hasStarted = false;
public:
virtual void mission()
{
std::cout << "LOL" << std::endl;
}
void startMission()
{
if (!hasStarted)
{
workingField = std::thread([this]() {
this->mission();
});
hasStarted = true;
}
}
virtual ~Mario()
{
if (hasStarted)
{
workingField.join();
}
}
};
class MarioWorker : public Mario
{
public:
void mission() override final
{
std::cout << "Mario works hard" << std::endl;
}
};
int main(int argc, char *argv[])
{
MarioWorker mw;
mw.mission();
mw.startMission();
}
How can I get a double line "Mario works hard", when one of them is executed in another thread?
In other words how a base class can execute an overridden method in parallel?
I'm using GCC 9.3
The problem is, the main thread is too fast. Your main method ends, the deconstruction of mw starts, MarioWorker gets destructed and once it starts destructing the Mario it joins the thread. The thread never sees the MarioWorker as it was already destructed, all it sees is the Mario.
I am very new to C++.
I have a class, and I want to create a thread inside a class's function. And that thread(function) will call and access the class function and variable as well.
At the beginning I tried to use Pthread, but only work outside a class, if I want to access the class function/variable I got an out of scope error.
I take a look at Boost/thread but it is not desirable because of I don't want to add any other library to my files(for other reason).
I did some research and cannot find any useful answers.
Please give some examples to guide me. Thank you so much!
Attempt using pthread(but I dont know how to deal with the situation I stated above):
#include <pthread.h>
void* print(void* data)
{
std::cout << *((std::string*)data) << "\n";
return NULL; // We could return data here if we wanted to
}
int main()
{
std::string message = "Hello, pthreads!";
pthread_t threadHandle;
pthread_create(&threadHandle, NULL, &print, &message);
// Wait for the thread to finish, then exit
pthread_join(threadHandle, NULL);
return 0;
}
You can pass a static member function to a pthread, and an instance of an object as its argument. The idiom goes something like this:
class Parallel
{
private:
pthread_t thread;
static void * staticEntryPoint(void * c);
void entryPoint();
public:
void start();
};
void Parallel::start()
{
pthread_create(&thread, NULL, Parallel::staticEntryPoint, this);
}
void * Parallel::staticEntryPoint(void * c)
{
((Parallel *) c)->entryPoint();
return NULL;
}
void Parallel::entryPoint()
{
// thread body
}
This is a pthread example. You can probably adapt it to use a std::thread without much difficulty.
#include <thread>
#include <string>
#include <iostream>
class Class
{
public:
Class(const std::string& s) : m_data(s) { }
~Class() { m_thread.join(); }
void runThread() { m_thread = std::thread(&Class::print, this); }
private:
std::string m_data;
std::thread m_thread;
void print() const { std::cout << m_data << '\n'; }
};
int main()
{
Class c("Hello, world!");
c.runThread();
}
Before I present the code which is found at the bottom of this post I would like to talk about the issue and the fix's that I do not desire. Okay basically I've created a GUI from scratch sort of and one requirement I wanted for this was allow components to have their own click executions so if i click a button or tab etc.. It would call Component->Execute(); Well normally you would do something like a switch statement of ids and if that components ID equaled n number then it would perform this action. Well that seemed kinda dumb to me and I thought there has to be a better way. I eventually tried to incorporate a feature in JAVA where you would do like Component.AddActionListener(new ActionListener( public void execute(ActionEvent ae) { })); or something like that and I thought that this feature has to be possible in C++. I eventually came across storing void functions into a variable in which could be executed at any time and modified at any time. However I hadn't noticed an issue and that was this only worked with static functions. So below you'll see my problem. I've patched the problem by using a pointer to SomeClass however this would mean having an individual function call for every class type is there no way to store a function callback to a non-static class member without doing the below strategy? and instead doing a strategy like the commented out code?
//Main.cpp
#include <iostream> //system requires this.
#include "SomeClass.h"
void DoSomething1(void)
{
std::cout << "We Called Static DoSomething1\n";
}
void DoSomething2(void)
{
std::cout << "We Called Static DoSomething2\n";
}
int main()
{
void (*function_call2)(SomeClass*);
void (*function_call)() = DoSomething1; //This works No Problems!
function_call(); //Will Call the DoSomething1(void);
function_call = DoSomething2; //This works No Problems!
function_call(); //Will Call the DoSomething2(void);
SomeClass *some = new SomeClass(); //Create a SomeClass pointer;
function_call = SomeClass::DoSomething3; //Static SomeClass::DoSomething3();
function_call(); //Will Call the SomeClass::DoSomething3(void);
//function_call = some->DoSomething4; //Non-Static SomeClass::DoSomething4 gives an error.
//function_call(); //Not used because of error above.
function_call2 = SomeClass::DoSomething5; //Store the SomeClass::DoSomething(SomeClass* some);
function_call2(some); //Call out SomeClass::DoSomething5 which calls on SomeClass::DoSomething4's non static member.
system("pause");
return 0;
}
//SomeClass.hpp
#pragma once
#include <iostream>
class SomeClass
{
public:
SomeClass();
~SomeClass();
public:
static void DoSomething3(void);
void DoSomething4(void);
static void DoSomething5(SomeClass* some);
};
//SomeClass.cpp
#include "SomeClass.h"
SomeClass::SomeClass(void)
{
}
SomeClass::~SomeClass(void)
{
}
void SomeClass::DoSomething3(void)
{
std::cout << "We Called Static DoSomething3\n";
}
void SomeClass::DoSomething4(void)
{
std::cout << "We Called Non-Static DoSomething4\n";
}
void SomeClass::DoSomething5(SomeClass *some)
{
some->DoSomething4();
}
Secondary Fix for what I'll do not an exact answer I wanted but it meets my needs for now along with allowing additional features which would have become overly complicate had this not existed.
//Component.hpp
#pragma once
#include <iostream>
#include <windows.h>
#include <d3dx9.h>
#include <d3d9.h>
#include "Constants.hpp"
#include "ScreenState.hpp"
#include "ComponentType.hpp"
using namespace std;
class Component
{
static void EMPTY(void) { }
static void EMPTY(int i) { }
public:
Component(void)
{
callback = EMPTY;
callback2 = EMPTY;
callback_id = -1;
}
Component* SetFunction(void (*callback)())
{
this->callback = callback;
return this;
}
Component* SetFunction(void (*callback2)(int), int id)
{
this->callback_id = id;
this->callback2 = callback2;
return this;
}
void execute(void)
{
callback();
callback2(callback_id);
}
}
The syntax for pointers-to-member-functions is as follows:
struct Foo
{
void bar(int, int);
void zip(int, int);
};
Foo x;
void (Foo::*p)(int, int) = &Foo::bar; // pointer
(x.*p)(1, 2); // invocation
p = &Foo::zip;
(x.*p)(3, 4); // invocation
Mind the additional parentheses in the function invocation, which is needed to get the correct operator precedence. The member-dereference operator is .* (and there's also ->* from an instance pointer).
I am trying to call the function hello which belongs to the class program1
#include <iostream>
using namespace std;
class program1
{
program1();
~program1();
hello();
}
program1::hello()
{
cout<<"hello";
}
int main()
{
program1.hello(); //Call it like a normal function...
cin.get();
}
Names inside a class are private by default.
class program1 {
public:
program1();
~program1();
void hello() ;
};
// ...
int main(int, char **) {
program1 myProgram;
myProgram.hello();
return 0;
}
Alternatively, you can invoke a method on a temporary:
int main(int, char **) {
program1().hello();
return 0;
}
but that's probably for later in the semester.
you forgot to create an object:
int main()
{
program1 p1;
p1.hello();
}
Class definition should end with ;
Secondly, you need to instantiate class to call members on it. ( i.e., creation of an object for the class )
In C++, methods should have return type.
program1::hello(); // method should have a return type.
class members and methods are private by default, which means you cannot access them outside the class-scope.
So, the class definition should be -
class program1
{
public: // Correction 1
program1();
~program1();
void hello(); // Correction 2
};
void program1::hello() // Need to place return type here too.
{
cout<<"hello";
}
Now on creation of object for class program1, it's method hello() can be called on it.
This version is edited. (make sure you include all the body of the methods)
#include <iostream>
using namespace std;
class program1
{
public: // To allow outer access
program1();
~program1();
void hello(); // The void
}; // Don't miss this semicolon
void program1::hello() // The void
{
cout<<"hello";
}
int main()
{
program1 prog; // Declare an obj
prog.hello(); //Call it like a normal function...
cin.get();
}
I noticed that you left out return type for your hello() function.
If you want to call hello() as a member function, then as suggested you should create an object to it.
program1 prog;
prog.hello();
If you want to call it without an object, the you should use static function.
class program1
{
public: // To allow outer access
program1();
~program1();
static void hello(); // The void
}
then you can call it this way:
program1::hello();
Therefore the working code should be this way:
#include <iostream>
using namespace std;
class program1 {
public:
void hello();
}; // Don't miss this semicolon
class program2 {
public:
void static hello(); // to demonstrate static function
}; // Don't miss this semicolon
void program1::hello() {
cout << "Hello, I'm program1." << endl;
}
void program2::hello() {
cout << "Hello, I'm program2." << endl;
}
int main(void) {
program1 prog1;
prog1.hello(); // Non-static function requires object
program2::hello(); // Static function doesn't
return 0; // Return 0
}