I have an abstract class as follows:
class AbstractClass : public std::enable_shared_from_this<AbstractClass> {
public:
virtual ~AbstractClass() = default;
virtual bool Start() = 0;
virtual void Stop() = 0;
};
This is the derived class:
class DerivedClass : public AbstractClass {
public:
bool Start() override;
void Stop() override;
}
I am trying to create an object of derived class and a thread for the derived class method in another file:
// Create object
derivedClass_.reset(...);
//Start a thread for the derived class method
std::unique_ptr<boost::thread> derivedClassThread_;
derivedClassThread_.reset(new boost::thread(std::bind(&DerivedClass::Start,
derivedClass_)));
When I compile this, I get some weird errors:
error: no type named 'type' in 'class std::result_of<bool
(DerivedClass::* const&(const volatile
std::shared_ptr&))()>'
Could someone help me out?
Your code is not selfcontained, so we have to guess things. Here's what I think you would have/want:
Live On Coliru
#include <boost/thread.hpp>
#include <memory>
#include <iostream>
class AbstractClass : public std::enable_shared_from_this<AbstractClass> {
public:
virtual ~AbstractClass() = default;
virtual bool Start() = 0;
virtual void Stop() = 0;
};
class DerivedClass : public AbstractClass {
public:
bool Start() override {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return true;
}
void Stop() override { }
};
int main()
{
// Create object
std::shared_ptr<AbstractClass> derivedClass_ =
std::make_shared<DerivedClass>();
// Start a thread for the derived class method
auto derivedClassThread_ = std::make_unique<boost::thread>(
[derivedClass_] { derivedClass_->Start(); });
if (derivedClassThread_ && derivedClassThread_->joinable())
derivedClassThread_->join();
derivedClassThread_ = std::make_unique<boost::thread>(
std::bind(&AbstractClass::Start, derivedClass_));
if (derivedClassThread_ && derivedClassThread_->joinable())
derivedClassThread_->join();
}
Which compiles without trouble.
Updated in response to the comment, showed that you can actually do it with std::bind just the same.
Prints:
virtual bool DerivedClass::Start()
virtual bool DerivedClass::Start()
Related
i'll try to create a structure for executing an overrided method in derived class.
My base code structure:
Base.h EDITED
class Base
{
protected:
virtual void Initialize() = 0;
virtual void Update() = 0;
public:
void Init();
void Upd();
};
Base.cpp
#include "Base.h"
void Base::Initialize() {}
void Base::Update() {}
void Base::Init() {
// Some logic
Initialize();
}
void Base::Upd() {
// Some logic
Update();
}
The following class is the class to be inherited from N other classes that implement Initialize() and Update() then:
Behaviour.h
#include <iostream>
#include "Base.h"
class Behaviour : public Base
{
protected:
virtual void Initialize();
virtual void Update();
};
Behaviour.cpp
#include "Behaviour.h"
void Bheaviour::Initialize() {
std::cout << "Initialize called!" << std::endl;
}
void Bheaviour::Update() {
std::cout << "Update called!" << std::endl;
}
Then I want to execute Behaviour Initialize() and Update() when is executed in the Base class. My main function is:
Core.cpp EDITED
#include "Behaviour.h"
int main() {
Base* base = new Behaviour();
base->Init();
while(!quit) {
base->Upd();
}
}
Thank's in advance for any suggestions!
Thanks for all suggestions, i've solved!
Change Base* base = new Base();
to
Base* base = new Bheviour;
and polmorphism will take care of everything else.
If you don't want to create an object out of base class better to declare it as an abstract class.
I have base class A which has factory method to create instances of derived classes B and C. B and C has start() overridden. There is do_work() which calls getInstance() and then calls start(). Now labmda inside spawn() does not store the instance of captures this pointer. So there is a scope problem. If I pass instance(boost::shared_ptr) to start explicitly and then capture it in lambda, then it works. How do I avoid passing instance to start()?
class B : public A {
public:
void start(){
boost::spawn(io_service, [this](boost::asio::yield_context yield)
{
// work
});
}
}
class C: public A {
public:
void start(){
boost::spawn(io_service, [this](boost::asio::yield_context yield)
{
// work
});
}
}
do_work() {
auto object = A::getInstance(); // this returns boost::shared_ptr and it does not store that instance
object->start();
}
class A {
public:
virtual void start () =0;
static boost::shared_ptr<A> getInstance() {
return boost::shared_ptr<A>(new B());
}
}
You should use enable_shared_from_this:
Live On Coliru
#define BOOST_COROUTINES_NO_DEPRECATION_WARNING
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
boost::asio::io_service io_service;
class A : public boost::enable_shared_from_this<A> {
public:
virtual void start() = 0;
static boost::shared_ptr<A> getInstance();
};
class B : public A {
public:
void start() {
auto self = shared_from_this();
boost::asio::spawn(io_service, [self](boost::asio::yield_context /*yield*/) {
// work
});
}
};
class C : public A {
public:
void start() {
auto self = shared_from_this();
boost::asio::spawn(io_service, [self](boost::asio::yield_context /*yield*/) {
// work
});
}
};
/*static*/ boost::shared_ptr<A> A::getInstance() { return boost::shared_ptr<A>(new B()); }
void do_work() {
auto object = A::getInstance(); // this returns boost::shared_ptr and it does not store that instance
object->start();
}
int main() {
}
Honestly, I don't know why the compiler let this pass. The start function doesn't exist in the A world.
Classes B and C haven't overridden anything unless there is a virtual function in their base class to override. Add a pure virtual start to class A, then decorate the B and C start functions with virtual. Then will those two classes have overridden something. I suspect that will result in the behavior you're expecting.
class A {
public:
static boost::shared_ptr<A> getInstance() {
return boost::shared_ptr<A>(new B());
}
virtual void start()=0;
};
class B : public A {
public:
virtual void start() {
// stuff specific to class B
}
};
class C : public A {
public:
virtual void start() {
// stuff specific to class C
}
};
I am no doubt overlooking something basic but my implementation is obviously flawed.
I am trying to require a derived classes to implement a method being called in a base class.
class IClock
{
public:
virtual void OnTimeExpired() = 0;
}
class Clock : public IClock
{
... // ABC not implemented
}
class Application : public Clock
{
... // ABC not implemented
}
class DerivedApp : public Application
{
public:
virtual void OnTimeExpired() { ... }
}
I rarely use pure ABCs, so I thought by not defining the pure virtual method in Clock and Application, it would require all derivatives of Application to define the OnTimeExpired() method.
I discovered this will compile and link (MSVS-2017) and if DerivedApp does not implement the method, the Clock object will call an undefined method and crash.
Why does this compile without the pure virtual method being implemented?
How do I force derived Application classes to implement the OnTimeExpired() method?
EDIT: The crash was due to unrelated error - I apologize. Nevertheless the questions I ask are still applicable.
As requested here is a complete, buildable, minimal example:
IClock.h:
#pragma once
class IClock
{
public:
virtual void OnClockTime() = 0;
};
Clock.h:
#pragma once
#include "IClock.h"
class Clock : public IClock
{
public:
Clock();
virtual ~Clock();
void ClockUpdate();
virtual void OnClockTime();
private:
float elapsed_time;
};
Clock.cpp:
#include "Clock.h"
Clock::Clock()
: elapsed_time(0.0f)
{
}
Clock::~Clock()
{
}
void Clock::ClockUpdate()
{
elapsed_time += 0.0000001f; // small ticks for testing
if (elapsed_time >= 1.0f) {
OnClockTime();
elapsed_time -= 1.0f;
}
}
void Clock::OnClockTime()
{}
ApplicationBase.h
#pragma once
#include "Clock.h"
class ApplicationBase : public Clock
{
public:
ApplicationBase();
virtual ~ApplicationBase();
virtual void Init(){}
virtual void Run(){}
protected:
bool app_run;
};
ApplicationBase.cpp:
#include "ApplicationBase.h"
ApplicationBase::ApplicationBase()
: app_run(false)
{
}
ApplicationBase::~ApplicationBase()
{
}
DerivedApp.h:
#pragma once
#include "ApplicationBase.h"
class DerivedApp : public ApplicationBase
{
public:
DerivedApp();
virtual ~DerivedApp();
virtual void Init() {}
virtual void Run();
//virtual void OnClockTime();
};
DerivedApp.cpp:
#include "DerivedApp.h"
#include <iostream>
DerivedApp::DerivedApp()
{
}
DerivedApp::~DerivedApp()
{
}
void DerivedApp::Run()
{
app_run = true;
while (app_run) {
ClockUpdate();
}
}
//void DerivedApp::OnClockTime()
//{
// static int counts(0);
// std::cout << "Tick..." << std::endl;
// counts++;
// if (counts >= 10)
// app_run = false;
//}
main.cpp
#include "DerivedApp.h"
class App : public DerivedApp
{
public:
App(){}
~App(){}
};
int wmain(int argc, wchar_t * argv[])
{
App *app = new App();
app->Init();
app->Run();
delete app;
}
Thanks to those who requested a minimal working example, I built it and it works exactly as I had hoped. The complier will complain about no instantiation of the ABC in the App class. If I remove the comments from DerivedApp::OnClockTime() it compiles and runs the way I wish. Obviously my actual code is not following this model as I thought, so now I need to reexamine where I went wrong. Thanks.
There is no keyword in C++ that forces a class to override some method. However, by making OnTimeExpired() pure virtual you're making IClock an abstract class. Any classes deriving from IClock that do not implement OnTimeExpired() will automatically become an abstract class too, thus not allowing you to create objects of these classes. This means that your code as-is is completely legal unless you try to make objects of these classes
class AbstractBase {
public:
virtual void someFunc() = 0; // Purely Virtual
};
class AbstractDerived : public AbstractBase {
public:
void someOtherFunc();
// Still abstract because the following is not declared-defined
// void someFunc() override { ... }
};
class NonAbstractDerivedA : public AbstractBase { // Derived From Base
public:
void someFunc() override { /* do this class's implementation*/ }
};
class NonAbstractDerivedB : public AbstractDerived { // Derived From AbstractDerived
public:
void someFunc() override { /* do this class's implementation*/ }
};
uses:
#include "above"
int main() {
AbstractBase base; // compiler error
AbstractDerived derived; // compiler error
NonAbstractDerivedA derivedA; // should be okay
NonAbstractDerivedB derivedB; // should be okay
return 0;
}
I have two classes Base and Derived inheriting from each other. In Base I want to create a thread executing the member function Handle of the class (TThread is MT library of ROOT). I want to override this handle function in Derived, but my program always executes the function from the base class rather than the one from the derived class. How can I change it so that the overridden Handle is executed instead?
Here is the code:
#include "TThread.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
thread = new TThread("BaseClass", (void(*)(void*))&Handle,(void*)this);
thread->Run();
}
private:
TThread *thread;
static void* Handle(void *arg)
{
cout<<"AAAA"<<endl;
}
};
class Derived : public Base
{
public:
Derived() : Base(){}
private:
static void* Handle(void *arg)
{
cout<<"BBBB"<<endl;
}
};
int main()
{
Derived *b = new Derived();
return 0;
}
You are trying to achieve polymorphism with on a non-virtual function.
The reference to Handle in your base class constructor gets resolved at compile time to always point to Base::Handle, no matter what the concrete type of the object at runtime will be. This can be fixed by changing Handle from a static to a virtual function.
The other problem is that you are trying to create the thread from the base class constructor. The derived object has not been fully constructed at this point, so you cannot polymorphically dispatch to Derived::Handle, even if you change it to a virtual function. A quick solution for this would be to move the thread construction to a Base::startThread() method and call that after the constructor has returned.
Make Handle virtual as #ComicSansMS says, and introduce a static member function to handle the virtual dispatch correctly:
#include "TThread.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base() : thread() {}
~Base() { wait(); }
void wait() {
if (thread)
{
thread->Join();
delete thread;
thread = NULL;
}
}
void start()
{
thread = new TThread("BaseClass", &Dispatch, this);
thread->Run();
}
private:
TThread *thread;
virtual void Handle()
{
cout<<"AAAA"<<endl;
}
static void* Dispatch(void *arg)
{
static_cast<Base*>(arg)->Handle();
return NULL;
}
};
class Derived : public Base
{
public:
Derived() { start(); }
~Derived() { wait(); }
private:
virtual void Handle()
{
cout<<"BBBB"<<endl;
}
};
int main()
{
Derived b;
}
I am experiencing a problem where a derived class does not have it's own version of a function called when it is called from a base class pointer. To better explain the classes are defined as below
Class Foo
{
public:
Foo();
virtual ~Foo();
virtual void Event();
}
//-----------------------
Class FooBar : public Foo
{
public:
FooBar();
virtual void Update() = 0;
virtual void Draw() = 0;
}
//-----------------------
Class FinalFoo : public FooBar
{
public:
FinalFoo();
void Update();
void Draw();
void Event();
}
There are other classes similar to FinalFoo. So I attempt to call Event on a pointer to a Foo object expecting that it would call the derived implementation. However, it would appear that it calls the base class version and that is all
FinalFoo* myThing = new FinalFoo();
Foo* baseThing = myThing;
baseThing->Event(); // I expected this to call FinalFoo::Event()
Assuming the above code is corrected, it actually does call FinalFoo::Event(). below is a complete and compilable example. Note, that it also adds the keyword override in strategic points: I'd bet that adding override in the original code, too (and compiling with a compiler aware of this keyword) would point out that your override isn't one.
#include <iostream>
class Foo
{
public:
virtual ~Foo() {}
virtual void Event() { std::cout << "Foo::Event()\n"; }
};
//-----------------------
class FooBar : public Foo
{
public:
virtual void Update() = 0;
};
//-----------------------
class FinalFoo : public FooBar
{
public:
FinalFoo() {}
void Update() override { std::cout << "FinalFoo::Update()\n"; }
void Event() override { std::cout << "FinalFoo::Event()\n"; }
};
int main()
{
FinalFoo myThing;
Foo* baseThing = &myThing;
baseThing->Event();
}