I've created a class named 'Device' which get inherited by multiple devices (for example, RFDevice, AccelleroDevice)
The Device class inherited a Thread class. This Threadclass includes a Pure virtual function named run. Is it possible to accesss this pure virtual function in RFDevice or AcelleroDevice.
So,
ThreadClass->DeviceClass->RFDeviceClass.
I've tried to add
' virtual void run(void) = 0' also in the device class but this wont work.
Greets,
Only if the virtual function is not private. If it is, then you cannot call it and are not supposed to, either:
class ThreadClass
{
public:
virtual ~ThreadClass() {}
private:
virtual void run() = 0;
};
class Device : public ThreadClass
{
};
class RFDevice : public Device
{
public:
void f()
{
run(); // compiler error
}
};
If it is protected or public, then it will work, provided there is an implementation of the function somewhere down the class hierarchy. But with the exception of the destructor, virtual functions should rarely be public or protected in C++:
class ThreadClass
{
public:
virtual ~ThreadClass() {}
protected:
virtual void run() = 0; // non-private virtual, strange
};
class Device : public ThreadClass
{
};
class RFDevice : public Device
{
protected:
virtual void run()
{
}
public:
void f()
{
run(); // works
}
};
Of course, this does not technically call the base function. And that's a good thing; you'd end up with a pure virtual function call otherwise, and your program would crash.
Perhaps what you need to do is to just implement the private virtual function. That would be the preferred class design:
class ThreadClass
{
public:
virtual ~ThreadClass() {}
void execute()
{
run();
}
private:
virtual void run() = 0;
};
class Device : public ThreadClass
{
};
class RFDevice : public Device
{
private:
virtual void run()
{
}
};
int main()
{
RFDevice d;
d.execute();
}
If you are not just maintaining a legacy code base, you should probably get rid of your thread class and use C++11 multi-threading.
Related
I get error when i try to compile this code.
class FunctionVisitor
{
public:
virtual ~FunctionVisitor() = default;
virtual void visit(SumTimer&) = 0;
virtual void visit(SumSelector&) = 0;
};
class timerVisitor : public FunctionVisitor
{
private:
std::string variableName;
std::string variableValue;
public:
timerVisitor(std::string varName, std::string varValue) : variableName(varName), variableValue(varValue) { }
virtual void visit(SumTimer& fun) override;
};
class selectorVisitor : public FunctionVisitor
{
private:
std::string variableName;
std::string variableValue;
public:
selectorVisitor(std::string varName, std::string varValue) : variableName(varName), variableValue(varValue) { }
virtual void visit(SumSelector& sel) override;
};
The reason is that i have pure virtual functions in the base class but each sub class only has defination of one function of the base class virtual function.
Can i have pure virtual functions in this case ?
Every class that inherits from abstract class in c++ and doesn't override all of its pure virtual functions is considered abstract and cannot be instantiated neither locally nor dynamically. You can either override the functions to do nothing (or return an exception)
virtual void visit(SumTimer& fun) override {}
or make the abstract class concrete and the functions do nothing by default
class FunctionVisitor
{
public:
virtual ~FunctionVisitor() = default;
virtual void visit(SumTimer&) {}
virtual void visit(SumSelector&) {}
};
What do you want to happen if you call a different function? E.g. if you call visit(SumSelector&) on a timerVisitor?
#user253751 i don't want any action in that case.
If you don't want anything to happen when the function is called but not overridden, then make the base class have a function that does nothing. Instead of
virtual void visit(SumTimer&) = 0;
write:
virtual void visit(SumTimer&) {}
Pure virtual (= 0) means that you want to force derived classes to override the function. If you don't want to do that, then don't make them pure virtual!
I have a baseclass, lets call it base_t. base_t has a function called void render(). I want that all classes that derive from base_t to have access to that function, but noone else. The render functions will be defined in base_t as virtual void render() = 0; making it pure virtual.
How can I achieve this in C++? Via friend? Or are there other methods of doing this?
To make it more clear, I want the class A (derived from base_t) to be able to access the function render() in class B (also derived from base_t) which is implemented by A and B but is pure virtual defined in base_t.
Here is an example:
class base_t
{
private:
virtual void render() = 0;
};
class A : public base_t
{
private:
virtual void render()
{
// Do Stuff
}
};
class B : public base_t
{
public:
void dostuff(A *classA)
{
// here I want to call render!
classA->render();
}
private:
virtual void render()
{
// Do Stuff
}
};
What about a simple:
class base_t
{
private:
virtual void render() = 0;
protected:
void renderOther(base_t& other){
other.render();
}
};
B can render A through the interface method keeping a correct encapsulation.
When trying to call a method setCurrentState Im getting the error:
StateMachine<Cow>::setCurrentState(std::shared_ptr<State<Cow>>)':
cannot convert argument 1 from 'std::shared_ptr<ChaseState>' to
'std::shared_ptr<State<Cow>>'
This indicates that a std::shared_ptr<ChaseState> is not a std::shared_ptr<State<Cow>> but why is it not?
The call to the function:
std::shared_ptr<ChaseState> initialState = std::make_shared<ChaseState>();
m_stateMachine->setCurrentState(initialState);
State.h
#pragma once
template <class entity_type>
class State
{
public:
virtual void enter(entity_type*) = 0;
virtual void execute(entity_type*) = 0;
virtual void exit(entity_type*) = 0;
};
ChaseState.h
class Cow;
class ChaseState : State<Cow>
{
public:
ChaseState();
// Inherited via State
virtual void enter(Cow*) override;
virtual void execute(Cow*) override;
virtual void exit(Cow*) override;
};
In my StateMachine I have private variable:
std::shared_ptr<State<entity_type>> m_currentState;
and the setCurrentState function:
void setCurrentState(std::shared_ptr<State<entity_type>> s) { m_currentState = s; }
As I understand the derived class ChaseState is a State (behause it inherits from state).
You need to declare your inheritance public. Class inheritance is private by default, meaning that you cannot cast from Derived to Base because the inheritance is not recognized outside of the class itself (same as how private members cannot be accessed outside the class).
To fix, make your inheritance public:
class ChaseState : public State<Cow>
// ^^^^^^
I need help for an implementation that uses multiple inheritance of Interfaces...
There is an existing code whith an interface which has a lot of functions. The instances are created using a factory.
class IBig
{
// Lot of pure virtual functions
};
And his inplementation:
class CBig: public IBig
{
// Implementation
}
I Want to split the interface in multiple smaller interfaces, but it should stay compatible to the existing code for some time.
Here is a sample of what I tried to do:
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : public IBaseA, public IBaseB
{
};
class CBaseA: public IBaseA
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: public IBaseB
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
The problem here is that the class CBig cannot be instanciated. The compiler says the functions DoA and DoB are pure virtual, even if they are inplemented in CBaseA and CBaseB. What should I do if i don't want to implement again the functions, just to call the function of the base class ?
NB: I know the design is ugly, but this is only temporary until the big interface can be replaced, and.... I want to understand ! ;-)
Thanks in advance !
Here we should use virtual inheritance. This feature assures that there is only one instance of your virtually-inherited base class when you instantiate a subclass. For your example, this would look like:
#include <cstdio>
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : virtual public IBaseA, virtual public IBaseB
// ^ ^
{
};
class CBaseA: virtual public IBaseA
// ^
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: virtual public IBaseB
// ^
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
int main()
{
CBig cb;
}
The above changes ensure that there are not extra declarations of DoA and DoB created when you inherit from IBaseA and IBaseB multiple times.
Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?
You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};
You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().
If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};