I have a IBase class and a Child class. I need to call different proc function in different child class. I'm not sure which form below is actually right, maybe neither XD.
Form 1: Exactly I don't want my IBase have any non-virtual function.
Form 2: There's a strange expression &IBase::proc could make some misunderstanding.
class IBase
{
public:
virtual void proc() = 0;
auto createBind()
{
return bind(&IBase::proc, this);
}
};
class Child :public IBase
{
public:
void proc() override
{
cout << "Hello World" << endl;
}
};
int main()
{
IBase* pointer = new Child;
//form 1
thread th(pointer->createBind());
th.join();
//form 2
thread th2(&IBase::proc, pointer);
th2.join();
cout << "Finish" << endl;
return 0;
}
I'm wondering how do you guys solve this circumstance in a real project.
The most idiomatic and robust way is probably this
std::thread t([=]{pointer->proc();});
No bind, no extraneous helper member function, no weird syntax with redundant mention of the class name.
I would use form 3 :-) :
thread* th3 = pointer->start();
th3->join();
with start in IBase as:
thread* start()
{
thread* t = new thread(createBind());
return t;
}
Which would in my opinion hide more details of the implementation and give the caller the API he expects (start a thread).
Related
Assuming we have the classical Base class and derived class like this
class B {
public:
virtual ~B() {
// calling it here is too late, see explanations
//common_pre_cleanup_function();
}
void common_pre_cleanup_function() { }
};
class D : public B {
public:
virtual ~D() {
// What if we forget to do this call in another derived class?
common_pre_cleanup_function();
}
};
How would you make sure a function like common_pre_cleanup_function() is called in all derived Ds destructors before the members of D are destroyed but without having to explicitly call this function in every destructor-implementation of a new D?
Background
In my current project we have a base class that implements certain parallelism and threading features and will eventually start a new thread that does the actual work.
In the destructor of this base class we wanted to make sure, that the thread is always stopped and joined so that it gets cleaned up properly.
However derived classes may create members that are used by this thread in the base class. So if we destroy objects of the derived class, these members are also destroyed. But at this time the thread that is managed by the base class can still be running and now wrongfully access destroyed members.
I'm aware that this isn't the smartest approach to solve the issue and probably splitting up the threading/parallelisation parts and the "actual work" parts into separate classes might be the much smarter idea. However I'm interested if there are any approaches that don't involve an entire rewrite of the existing code base.
This code here is closer to our situation
class BackgroundTask {
public:
virtual ~BackgroundTask() {
// if we forget to call stop() in the derived classes, we will
// at this point have already destroyed any derived members
// while the thread might still run and access them; so how/where
// can we put this call?
//stop();
}
void stop() {
cancelFlag_.set();
thread_.join();
}
// more functions helping with Background tasks
private:
Thread thread_;
Condition cancelFlag_;
};
class MyTask : public BackgroundTask {
public:
virtual ~MyTask() {
// with the current case, we have to remember to call
// this function in all destructors in classes derived
// from BackgroundTask; that's what I want to avoid
stop();
}
private:
std::unique_ptr<MyClass> member;
};
Quite simply you don't. The best thing to do in this situation is to redesign how everything works to prevent this from being a problem.
But lets face it, in all likelihood you don't have the time and/or resources to achieve that. So your second best option (in my opinion) is to ensure that any call to the destroyed members of the derived class kills you application immediately with a very clear error message.
If a system must fail, fail early.
You might do something like:
template <typename TaskImpl>
class Task final : public TaskImpl
{
static_assert(std::is_base_of<BackgroundTask, TaskImpl>);
public:
virtual ~Task() { stop(); }
};
And then
class MyTaskImpl : public BackgroundTask
{
// ...
private:
std::unique_ptr<MyClass> member;
};
using MyTask = Task<MyTaskImpl>;
While I agree with comments that the design is flawed .....
Assuming that the objects are dynamically allocated, one solution is to make the destructors virtual and protected, and use a separate function to take care of calling the "pre-cleanup" before destroying the objects. For example;
class B
{
public:
void die()
{
common_pre_cleanup_function();
delete this;
};
protected:
virtual ~B() {};
private:
void common_pre_cleanup_function() { };
};
class D : public B
{
protected:
virtual ~D() {};
};
int main()
{
B *b = new D;
b->die();
}
This has a few limitations for the user of the class. In particular, behaviour is undefined if
the object is not created using a new expression;
any non-static member function of the object is called after calling die()
any non-static data member is accessed after calling die()
This also means that, if you maintain a set of objects (like a vector of pointers, B*) then it is necessary to remove the pointer from the list to ensure no usage of the object after it has died.
The protected destructors prevent a few things. Functions that are not members of friends of B or D cannot;
Create a B or a D of automatic storage duration
Use operator delete directly. For example, a statement delete b; in main() above will not compile. This also prevents destroying an object before calling the "pre-cleanup"
Edit: I realized this doesn't aswer your question but I'll leave it here for reference.
As mentioned earlier, each object should be responsible for managing its own resources so your design is a bit flawed to begin with.
Consider the following example. The TaskRunner is responsible for firing up a thread, and shutting it down when the constructor is called (textbook RAII). The Task class specifies what to do during the lifetime of the task, through pure virtual inheritance.
#include <atomic>
#include <future>
#include <iostream>
#include <memory>
struct Task {
virtual void run( ) = 0;
virtual ~Task( ) {
}
};
class TaskRunner final {
std::unique_ptr<Task> task;
std::future<void> fut;
std::atomic<bool> terminate;
public:
TaskRunner(std::unique_ptr<Task>&& task)
: task {std::move(task)}
, terminate {false} {
fut = std::async(std::launch::async, [this] {
while(!terminate) {
this->task->run( );
}
this->task.reset( );
});
}
TaskRunner(TaskRunner&&) = delete;
TaskRunner& operator=(TaskRunner&&) = delete;
TaskRunner(const TaskRunner&) = delete;
TaskRunner& operator=(const TaskRunner&) = delete;
~TaskRunner( ) {
terminate = true;
fut.wait( ); // Block until cleanup is completed
std::cout << "~TaskRunner()" << std::endl;
}
};
struct MyTask : public Task {
int i = 0;
void
run( ) {
// Do important stuf here, don't block.
std::cout << "MyTask::run() " << i++ << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds {100});
}
~MyTask( ) override {
// Clean up stuff here, run() is guaranteed to never be run again
std::cout << "~MyTask()" << std::endl;
}
};
int
main( ) {
TaskRunner t {std::make_unique<MyTask>( )};
std::this_thread::sleep_for(std::chrono::seconds {1});
}
Output
MyTask::run() 0
MyTask::run() 1
MyTask::run() 2
MyTask::run() 3
MyTask::run() 4
MyTask::run() 5
MyTask::run() 6
MyTask::run() 7
MyTask::run() 8
MyTask::run() 9
~MyTask()
~TaskRunner()
This question already has answers here:
C++ virtual method not called as desired
(4 answers)
Closed 5 years ago.
I have an interface from which a user derives multiple classes which I have no knowledge of but still I want to call these derived classes common method Run().
The Event class is intended to be an interface so I know how to call my unknown UserEvents derived class, since they all must have that Run() method implemented.
I currently have some code and get an error that CallEvent can't allocate an abstract Event. I understand the error, but don't know how I can go about and execute this correctly.
Here's some minimal code example (WandBox):
#include <iostream>
class Event
{
public:
virtual void Run(int Param) = 0;
};
// This is a user event and I have no idea what the class name is,
// but I still have to call it's method Run() that is common to the interface "Event"
class UserEvent : public Event
{
public:
virtual void Run(int Param) { std::cout << "Derived Event Dispatched " << Param << std::endl;};
};
// This parameter is of pure abstract base class Event because
// I have no idea what my user class is called.
void CallEvent(Event WhatEvent)
{
WhatEvent.Run(123);
};
int main()
{
std::cout << "Hello World!" << std::endl;
UserEvent mE;
CallEvent(mE);
}
I took your sample code (Like so) and tried to make it running (for illustration):
#include <iostream>
class Event {
public:
virtual void Run(int Param) = 0;
};
// This is a user event and I have no idea what the class name is,
// but I still have to call it's method Run() that is common to the interface "Event"
class UserEvent: public Event {
public:
virtual void Run(int Param)
{
std::cout << "Derived Event Dispatched " << Param << std::endl;
}
};
// This parameter is of pure abstract base class Event because
// I have no idea what my user class is called.
void CallEvent(Event *WhatEvent)
{
std::cout << "in CallEvent(Event *WhatEvent):" << std::endl;
// Huh? WhatEvent = new Event();
// wrong: WhatEvent.Run(123);
// Instead, use ->.
// For pointers, check for non-nullptr is very reasonable:
WhatEvent->Run(123);
// obsolete: delete WhatEvent;
}
// second approach using a reference (as recommended in comments):
void CallEvent(Event &WhatEvent)
{
std::cout << "in CallEvent(Event &WhatEvent):" << std::endl;
WhatEvent.Run(123); // for references - select operator . is fine
}
int main()
{
std::cout << "Hello World!" << std::endl;
/* nullptr does not make sense:
* UserEvent *mE = nullptr;
* Go back to original approach:
*/
UserEvent mE;
CallEvent(&mE); // calling the first (with Event*)
CallEvent(mE); // calling the second (with Event&)
return 0;
}
Now, it is compilable and runnable. Output:
Hello World!
in CallEvent(Event *WhatEvent):
Derived Event Dispatched 123
in CallEvent(Event &WhatEvent):
Derived Event Dispatched 123
(Life demo on ideone)
I annotated every modification in comments inside the sample code.
I have a base class that can start background thread, and stop it when needed. That thread calls two virtual methods Open() and Close(). So all inherited classes can re-implement this methods, but not starting/stoping thread routine (it more difficult than in example). I want to follow RAII principle and start/stop thid thread in constructor/destructor of base class.
The problem is, that calling virtual methods in constructor/destructor is a bad practice and didn't work in my case.
Here is a shot example of my problem:
#include <iostream>
#include <thread>
#include <atomic>
class Base {
public:
Base() {
bg_thread_ = std::thread([this] {
Open();
while(!is_stop_) {
// do stuff
}
Close();
});
}
~Base() {
is_stop_ = true;
if(bg_thread_.joinable()) {
bg_thread_.join();
}
}
private:
virtual void Open() {
std::cout << "Base open" << std::endl;
}
virtual void Close() {
std::cout << "Base close" << std::endl;
}
std::thread bg_thread_;
std::atomic<bool> is_stop_{false};
};
class Inherited : public Base {
virtual void Open() override {
std::cout << "Inherited open" << std::endl;
}
virtual void Close() override {
std::cout << "Inherited close" << std::endl;
}
};
int main() {
Inherited inherited;
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
The output is:
Inherited open
Base close
And without sleep is:
Base open
Base close
My current approach is to call Start() method after constructor and Stop() before destructor, but I want solution with RAII.
void Start() {
bg_thread_ = std::thread([this] {
Open();
while(!is_stop_) {
// do stuff
}
Close();
});
}
void Stop() {
is_stop_ = true;
if(bg_thread_.joinable()) {
bg_thread_.join();
}
}
The problem is independent of threads. If you call virtual methods in the constructor of the Base, the Inherited object is not yet created so the Base implementations of the methods are called (or you get an error if they are pure virtual). If you call virtual methods in the destructor of Base the Inherited object is already destroyed so again the Base version of the virtual methods are called again.
Calling the methods from another thread does not change this behaviour. But the starting of the thread might take longer than the construction of the Inherited object so the object is fully constructed and the Inherited methods are called at the beginning of the worker thread.
One solution is to move the RAII to another object. So you don't call Start and Stop in Bases constructor and destructor. Then you can build a StartStopThing which takes a Base (by reference or by pointer) and calls Start and Stop in its constructor and destructor. Or you build a StartStopThing template class which takes Inherited as template argument, builds an Inherited object and calls the Start and Stop methods.
According to my book, if I want to make an array of objects that are not in the same class but in the same class hierarchy, I need to use pointers:
class text
{
public:
void write(string text);
void show();
private:
string texte;
};
void text::write(string text)
{
texte = text;
}
void text::show()
{
cout << texte;
}
class text_with_stars : public text
{
public:
void show();
};
void text_with_stars::show()
{
cout << "*";
text::show();
cout << "*";
}
int main()
{
text* array[2];
array[0] = new text;
array[0]->write("Hello");
text_with_stars* pointer = new text_with_stars;
pointer->write("Hi");
array[1] = pointer;
for (int i=0;i<2;i++)
{
array[i]->show();
}
return 0;
}
But when I do this, the output is "HelloHi" meaning that the second object used the show version that is from text and not from text_with_stars, but I made it exactly the same way that the book described. What Is the problem??
Here is what is written in the book:
Question* quiz[2];
quiz[0] = new Question;
quiz[0]->set_text("Who was the inventor of C++?");
quiz[0]->set_answer("Bjarne Stroustrup");
ChoiceQuestion* cq_pointer = new ChoiceQuestion;
cq_pointer->set_text("In which country was the inventor of C++ born?")
cq_pointer->add_choice("Australia",false);
...
quiz[1] = cq_pointer;
The chapter right next to the one I was reading is about virtual functions and it explains that the system will always use the member functions of Question instead of ChoiceQuestion, looks like I should read more before asking questions on internet!
void show()
needs to be virtual in the base class if you want to use methods from derived classes from base class pointers
The reason this is happening is because the function you are calling is non-virtual.
Let's say we have a class Parent and a class Child inheriting from the parent:
class Parent {
public:
void f() {
cout << "Parent::f()" << endl;
}
};
class Child : public Parent {
public:
void f() {
cout << "Child::f()" << endl;
}
};
Now, let's make a pointer to a Parent and store a Child in it (polymorphism):
Parent *ptr = new Child;
ptr->f();
At this point, the compiler sees ptr having type Parent* and determines that the function to be called is Parent::f().
In order to call Child::f() when dealing with polymorphism? The Parent::f() must be defined virtual. The compiler then generates code to check at run-time the value that is stored in memory to call the appropriate (child) function.
In short: ONLY when a function is virtual and is called on a pointer or reference, a memory lookup is made to determine the actual type at that point in memory. Otherwise it is not.
I'm not sure if this has already been answered somewhere or if what I'm asking is feasible. I'm not so familiar with C++ and OOP in general so forgive me if I'm asking something too obvious, as my mind is a bit stuck right now.
Anyway, what I want to deal with is:
I'm using a framework that handles some callbacks from an app. The API has a class for these events and the callback function as pure virtual function. For example:
class A {
public:
A(){};
~A(){};
virtual void myCallback(){} = 0
};
In my code I'm implementing this callback and I have something like:
class B : A {
public:
B(){
std::cout<<"I'm a ClassB object";
};
~B(){};
void myCallback(){
std::cout<<"Hello callback";
};
};
Now in my main suppose that I'm having something like that:
int main(){
int x=1;
B objB;
//Do some stuff for a while
return 1;
}
I can see upon instantiating the B object the "I'm a ClassB object" message and I can see upon firing the event the "Hello callback" message.
So what I'm asking here is how I can get inside my callback the value of "x" coming from main ? Can I re-implement the callback inside the main somehow? Do you think that my approach on this is correct ?
What I want is to implement pure virtual callback function inside my main by having an object of class B. Or even to somehow get the value of x inside the myCallback function.
I'm not sure if I'm clear enough or if I messed anything up
If I understand the question, what you want is usually called a closure. You want myCallback to know the value of x inside main. There are several ways of doing this, the most straightforward will look something like following:
class B : public A {
public:
B(int x) x(x) {
std::cout<<"I'm a ClassB object";
}
~B() = default;
void myCallback() {
std::cout << "Hello callback, x is " << x << "\n";
}
private:
int x;
};
int main() {
int x = 1;
B objB(x);
//Do some stuff for a while
return 0;
}