I am not able to call a pure virtual function of the base class within a lambda of the inherited class. I simplified the problem to the following easy example...
The usecase is, that the class Test should again be a base class of some other class, that will implement the pure virtual function (anywhere in the program).
class Base
{
public:
virtual void DoSomething(Parameter* p) = 0;
};
class Test : public Base
{
public:
void addFunction()
{
mFunction = [this] (Parameter* p) { Base::DoSomething(p); };
}
private:
std::function<void(Parameter* p)> mFunction;
};
I get following compilation error:
undefined reference to Base::DoSomething(Parameter* p)
My current solution is to call a tempFunction in the base class, and then call the virtual function. But this seems more like a hack... and means unnecessary overhead:
class Base
{
public:
virtual void DoSomething(Parameter* p) = 0;
protected:
void tempDoSomething(Parameter* p) { DoSomething(p); } // call this function instead
};
I am using Android-NDK with clang compiler.
Related
I have a class hierarchy like this:
class Base
{
public:
void start() { init(); }
private:
virtual void init() = 0;
};
class Default : public Base
{
private:
virtual void init() override {/*default implementation*/};
};
class Special : public Default
{
private:
virtual void init() override final {/*specialized implementation*/};
}
Which works alright if I call start() on an object of type Special;
Now I have a case where in the implementation in the Special class I want to call the implementation of the Default class.
Normally that would work with Default::init();, but will fail here due to the Defaults declaration of this is private.
Obviously one solution is to change this from private to protected, but I'd like to ask if there is another way? Rather than allowing any child to call this function directly, I'd like to limit this to calls that are initiated via virtual functions already defined in the Base or Default class.
Is there some option or modifier that would allow member function calls to be only allowed from child classes if they are within (the same) overriding virtual member functions?
C++ doesn't provide means to achieve this directly, so you'd have to work around, e. g. in piece of code below.
Well, if you absolutely want to. I personally would rather just fall back to making the functions protected, document what they are intended for and when to be called, and then just trust the deriving classes to do the stuff right. That in the end keeps the interfaces cleaner and doesn't rely on a rather unusual (and perhaps ugly) pattern (actually passing this twice).
class Base
{
public:
virtual ~Base() { }
void start()
{
InitProxy p(*this);
init(p);
}
protected:
class InitProxy
{
public:
InitProxy(InitProxy const&) = delete;
void init()
{
m_base.Base::init(*this);
}
private:
friend class Base;
Base& m_base;
InitProxy(Base& base)
: m_base(base)
{ }
};
private:
virtual void init(InitProxy& proxy) { }
};
class Derived : public Base
{
void init(InitProxy& proxy) override
{
proxy.init();
}
};
You could let the proxy accept a member function pointer, if you want to apply this constraint to more than one function, so you wouldn't have to re-write the proxy for every function separately. Possibly you'd need to make a template from then, if function parameters differ.
Forward declare Special, and make it a friend of Default:
class Base
{
public:
void start() { init(); }
private:
virtual void init() = 0;
};
class Special; // Forward declaration
class Default : public Base
{
private:
virtual void init() override {/*default implementation*/}
friend class Special; // Friend declaration
};
class Special : public Default
{
private:
virtual void init() override final {
Default::init();
/*Other implementation*/
}
};
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.
Why I can't create new instance of class which is derived class of my abstract base class? My derived class has overriden base method but with different parametr which is derived class of base class param.
class BaseArg {
} ;
class DerivedArg :public BaseArg{
} ;
class BaseHandler{
public:
virtual void handle(BaseArg* arg) = 0;
} ;
DerivedHandler {
void handle(DerivedArg* arg) {}
} ;
auto x = new DerivedHandler() ;
Compiler returns "Cannot Instantiate abstract class"
Why? In my opinion it should works.
class BaseHandler
{
public:
virtual void handle(BaseArg* arg) = 0;
};
You declare a virtual function handle that needs to be able to accept any kind of BaseArg.
class DerivedHandler : public BaseHandler
{
public:
void handle(DerivedArg* arg) { }
};
Your overriding function just accepts one specific type of BaseArg, so it does not suffice to provide an implementation for the (more general!) inherited function handle. The other way round would have worked (in theory only, see below) – or it would have (truely) worked with return type, as a DerivedArg returned always is a BaseArg, too...
For overview:
class Base
{
public:
virtual void f0(BaseArg* arg) = 0;
virtual void f1(DerivedArg* arg) = 0;
virtual BaseArg* f2() = 0;
virtual DerivedArg* f3() = 0;
};
class Derived : public Base
{
public:
virtual void f0(DerivedArg* arg) override; // FAILS!
virtual void f1(BaseArg* arg) override; // (fine...)(*)
virtual DerivedArg* f2() override; // fine...
virtual BaseArg* f3() override; // FAILS!
};
(*) Actually, this case would have been fine in theory. C++, however, does not support contravariant function arguments, so this case will fail, too (the new function considered being an overload only)!
For more information, have a look at Wikipedia.
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>
// ^^^^^^
How to call base class method if it is not abstract.
class WithAbstMethod {
public:
virtual void do() = 0;
}
class WithImplMethod : public WithAbstMethod {
public:
virtual void do() {
// do something
}
}
template<typename BaseT>
class DerivedClass : BaseT {
public:
virtual void do() {
BaseT::do(); // here is a question. How to modify code, so that do() is called if it is not abstract?
// do something
}
}
void main() {
DerivedClass<WithAbstMethod> d1;
d1.do(); // only DerivedClass::do() should be called
DerivedClass<WithImplMethod> d2;
d2.do(); // both WithImplMethod::do() and DerivedClass::do() should be called
}
Is it possible to do this using templates in compile-time without much code (instantiate DerivedClass::do() method with BaseT::do() call and without depending on BaseT type)?
Obviously, provide implementation in WithAbstMethod class is not an option. Code above is pseudo-code so may contain minor errors.
Actually, providing an implementation for WithAbstMethod::do() might be an option. Abstract functions are allowed to have an implementation.
void WithAbstMethod::do()
{
// do nothing...
}