How to handle return of Abstract Objects - c++

I'm facing the following situation:
class Base{
virtual void Stuff() = 0;
};
class ConcreteA : public Base{
void Stuff() {};
};
class ConcreteB : public Base{
void Stuff() {};
};
class Context {
Base exec() {
ConcreteA conc_a();
return a;
}
};
Of course the compiler gives me an error since Base is abstract. However, I'd need that exec() return a Base type. I know that I can make the compiler happy using pointers or references, but since the object ConcreteA is created in exec(), returning by value is the best way to avoid dangling references or pointer with undefined ownership.
Is there a way to avoid using pointers or references to handle this kind of situations?

This looks like a perfect, simple use case for std::unique_ptr. Here is a C++14 example:
#include <memory>
#include <iostream>
class Base{
public:
virtual ~Base() {}
virtual void Stuff() = 0;
};
class ConcreteA : public Base{
void Stuff() { std::cout << "ConcreteA::Stuff\n"; };
};
class ConcreteB : public Base{
void Stuff() { std::cout << "ConcreteB::Stuff\n";};
};
class Context {
public:
std::unique_ptr<Base> exec() {
return std::make_unique<ConcreteA>();
}
};
int main()
{
Context c;
auto base_ptr = c.exec();
base_ptr->Stuff();
}
Memory is automatically deleted when base_ptr in main goes out of scope.
Note that I also made the Base destructor virtual. Perhaps you just left it out in your code example for the sake of brevity, but its importance should be stressed, and I think it should be kept even in short example code.

Related

Best way to handle a virtual method for copying a polymorphic object if its base class should not be abstract?

I need to copy an object of a polymorphic class having a base pointer. I know that I can implement a virtual method for this. But what if the base class should not be abstract? Leaving the method without pure-specifier can lead to run-time bugs, if you forget reimplement it in the derived. It's uncomfortable. What is the best way to handle this?
There are good reasons why you should never want to instantiate a base class.
If you do need to make a empty final class use the following.
class IBase
{
virtual void SharedCode()
{
1 + 1;
/// code here
};
virtual void AbstractDecalration() = 0;
};
class Base final: IBase
{
void AbstractDecalration() override;
};
Base b{};
All Future Derived classes will be able to use the SharedCode of IBase and you will have a Instantiated class of Base that is final. This is for future proofing your code base.
However I realize that is not the question you asked so here is a implementation were I use a simple check to the vtable pointer of the class to see if I have the correct class.
This is a runtime check and doesn't work across libraries use dynamic_assert if that is the case.
#include <memory>
#include <type_traits>
#include <assert.h>
class Base {
public:
auto clone() const
{
return std::unique_ptr<Base>(this->clone_impl());
}
private:
virtual Base* clone_impl() const
{
Base b{};
int* bVtablePtr = (int*)((int*)&b)[0];
int* thisVtablePtr = (int*)((int*)this)[0];
assert(bVtablePtr == thisVtablePtr);
return new Base(*this);
}
};
class Derived : public Base
{
auto clone() const
{
return std::unique_ptr<Derived>(this->clone_impl());
}
virtual Derived* clone_impl() const
{
return new Derived();
}
};
class Falty : public Base{};
int main(){
std::unique_ptr<Derived> good(new Derived());
std::unique_ptr<Falty> falty(new Falty());
good->clone(); // oke
falty->clone(); // this function asserts at runtime
}
Note the private clone_impl and public unique_ptr retuning clone method.
Very usefull to prevent memory leaks in your code
You can achieve what you want by introducing another abstract base class plus using CRPT for clone function. Then, clone will be automatically implemented in all derived classes "for free" (without manual retyping). Example:
struct Abstract
{
virtual ~Abstract() {}
virtual Abstract* clone() const = 0;
virtual void say() const = 0;
};
template <typename B, typename D>
struct AbstractCloneable : B
{
virtual B* clone() const override
{
return new D(static_cast<const D&>(*this));
}
};
// original base class
struct Base : AbstractCloneable<Abstract, Base>
{
virtual void say() const override
{
std::cout << "Base" << std::endl;
}
};
// original derived class #1
struct Derived1 : AbstractCloneable<Base, Derived1>
{
virtual void say() const override
{
std::cout << "Derived1" << std::endl;
}
};
And a test program:
int main()
{
std::unique_ptr<Abstract> ptr1 = std::make_unique<Base>();
ptr1->say();
std::unique_ptr<Abstract> ptr1_copy{ ptr1->clone() };
ptr1_copy->say();
std::unique_ptr<Abstract> ptr2 = std::make_unique<Derived1>();
ptr2->say();
std::unique_ptr<Abstract> ptr2_copy{ ptr2->clone() };
ptr2_copy->say();
}
Which outputs:
Base
Base
Derived1
Derived1
Live demo: https://godbolt.org/z/3FeSTd
See this article for more details and explanations: C++: Polymorphic cloning and the CRTP (Curiously Recurring Template Pattern).

Troubles with factory method with shared pointers and restricted constructors

This compiles OK, but gives runtime error on the b->hello() call. My intention is to use dynamic type of the b pointer and call Inherited::hello() version.
Help :-)
#include <iostream>
#include <memory>
using namespace std;
class Base {
public:
static shared_ptr<Base> factory();
string hello(){};
virtual ~Base() {};
protected:
Base(){};
};
class InheritedA : public Base{
friend class Base;
public:
string hello() {return "I am iA";}
protected:
InheritedA() {};
};
shared_ptr<Base> Base::factory() {
shared_ptr<Base> ptrB;
shared_ptr<InheritedA> ptrA;
ptrA = shared_ptr<InheritedA>(new InheritedA);
ptrB = dynamic_pointer_cast<Base>(ptrA);
return ptrB;
};
int main() {
shared_ptr<Base> b;
b = Base::factory();
cout << b->hello();
return 0;
}
You are forgetting one very important thing when it comes to polymorphism and overriding base-class functions: The functions must be virtual.
Since your function isn't virtual you call the Base::hello function, and since it doesn't return anything you will have undefined behavior, leading to the crash you experience.
You can ask the compiler to help you detect such cases by using the override specifier:
class InheritedA : public Base{
friend class Base;
public:
string hello() override // Tell the compiler that this function should
// override the function from the parent class
{return "I am iA";}
protected:
InheritedA() {};
};
If you use the override specifier the compiler will issue an error if the function is not virtual.
Besides marking the base class function virtual, you really should either return something, anything, from the function, or make it abstract:
class Base {
public:
static shared_ptr<Base> factory();
// Make the function a pure abstract function that must be overridden
virtual string hello() = 0;
virtual ~Base() {};
protected:
Base(){};
};
Obviously - virtual was missing in Base::hello() declaration, also override after InheritedA::hello() .
#include <iostream>
#include <memory>
using namespace std;
class Base {
public:
static shared_ptr<Base> factory();
virtual string hello(){};
virtual ~Base() {};
protected:
Base(){};
};
class InheritedA : public Base{
friend class Base;
public:
string hello() override {return "I am iA";}
protected:
InheritedA() {};
};
shared_ptr<Base> Base::factory() {
shared_ptr<Base> ptrB;
shared_ptr<InheritedA> ptrA;
ptrA = shared_ptr<InheritedA>(new InheritedA);
//some very complex stuff here
ptrB = dynamic_pointer_cast<Base>(ptrA);
return ptrB;
};
int main() {
shared_ptr<Base> b;
b = Base::factory();
cout << b->hello();
return 0;
}

overloading functions with base class smart pointers

I have 3 classes: the first a pure virtual base class base with derived classes derived1, derived2...
the second foo holds a smart ptr to a base class
the third holds a smart ptr to foo and has an overloaded member function which I want to depend on the derived class the ptr in foo points to.
Here is the working code
#include<iostream>
#include<boost/shared_ptr.hpp>
using namespace std;
class base{
public:
base(){}
~base(){}
virtual void FuncDer()=0;
};
class derived1 : public base{
derived1(){}
virtual void FuncDer(){
cout<<"derived function1!"<<endl;
}
};
class derived2 : public base{
derived2(){}
virtual void FuncDer(){
cout<<"derived function2!"<<endl;
}
};
class foo {
public:
foo();
~foo();
boost::shared_ptr<base> get_base_ptr(){
return base_obj;
}
private:
boost::shared_ptr<base> base_obj;
};
class bar {
public:
bar();
~bar();
void callfunc(){
func(foo_ptr->get_base_ptr());
}
private:
boost::shared_ptr<foo> foo_ptr;
void func(boost::shared_ptr<derived1>);
void func(boost::shared_ptr<derived2>);
};
int main()
{
cout<<"test"<<endl;
return 0;
}
This however seems to fail with the error no matching member function. So my question is firstly is there something obviously wrong with this approach and secondly is there a more efficient / object oriented design approach which better deals with this type of problem.
In principle this is the right way of doing it: Call the function on the base and polymorphism will do the right thing.
However, your code won't compile: The func definitions in bar aren't valid (at least I'm not sure what you intended them for - what are they supposed to implement?) and the func call in callfunc dereferences the pointer twice.
If you need concrete fixes, give the exact error.

C++ is it possible to make a class extend one class and be a realization of an interface at the same time?

Coluld you provide a simple code example? (sorry C++ nube) and how to call a function from the class you are extending?
A bit useful example: :-)
class CImplementation
{
public:
void doFoo();
};
void CImplementation::doFoo()
{
//implementation
}
class IInterface
{
public:
virtual void foo()=0;
};
class DerivedFromImplementationAndInterface : public CImplementation, public IInterface
{
virtual void foo();
};
void DerivedFromImplementationAndInterface::foo()
{
doFoo();
}
//possible usage:
void method(IInterface& aInterface)
{
aInterface.foo();
}
void test()
{
IInterface* d = new DerivedFromImplementationAndInterface;
method(*d);
}
In C++, you can extend multiple classes, it's called multiple inheritance. Most probably this is what you're looking for. Please read a good book about multiple inheritance and C++ (a quick introduction: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm), because there are many pitfalls and details to pay attention to.
Example for multiple inheritance:
class A { ... };
class B { ... };
class C: public A, public B {}; // C inherits from A and B.
C++ doesn't explicitly have interfaces, the equivalent of an interface in Java is usually implemented with a class having only pure virtual functions (plus constructors, destructor, copy assignment):
#include <iostream>
// interface
class Fooable {
public:
virtual int foo() = 0;
virtual ~Fooable() {}
};
// base class
class Base {
public:
void non_virtual_function() { std::cout << "Base::non_virtual_function\n"; }
virtual void virtual_function() { std::cout << "Base::virtual_function\n"; }
};
// derived class, inherits from both Base "class" and Fooable "interface"
class Derived: public Base, public Fooable {
public:
virtual int foo() {
// call base class function
Base::non_virtual_function();
// virtual call to function defined in base class, overridden here
virtual_function();
}
virtual void virtual_function() {
// call base class implementation of virtual function directly (rare)
Base::virtual_function();
std::cout << "Derived::virtual_function\n";
}
void non_virtual_function() {
// not called
std::cout << "Derived::non_virtual_function\n";
}
};
int main() {
Derived d;
d.foo();
}
Not sure what you're asking:
class A
{
public:
void method();
};
class B
{
public:
void method();
};
class C : public A, public B
{
public:
void callingMethod();
};
void C::callingMethod()
{
// Here you can just call A::method() or B::method() directly.
A::method();
B::method();
}
Note that multiple inheritance can lead to really hard-to-solve problems and I would recommend to only use it when necessary.
The question as stated,
C++ is it possible to make a class extend one class and implement another?
does not make much sense. The answer to that is just "yes". You can derive from any number of classes: C++ fully support multiple inheritance.
So, given that the question as stated isn't really meaningful, it's at least possible that you meant to ask
C++ is it possible to make a class extend one class and thereby implement another?
The answer to this question is also yes, but it's not trivial. It involves virtual inheritance. Which is quite tricky.
Here's an example:
#include <iostream>
void say( char const s[] ) { std::cout << s << std::endl; }
class TalkerInterface
{
public:
virtual void saySomething() const = 0;
};
class TalkerImpl
: public virtual TalkerInterface
{
public:
void saySomething() const
{
say( "TalkerImpl!" );
}
};
class MyAbstractClass
: public virtual TalkerInterface
{
public:
void foo() const { saySomething(); }
};
class MyClass
: public MyAbstractClass
, public TalkerImpl
{};
int main()
{
MyClass().foo();
}
The virtual inheritance ensures that there is only one sub-object of type TalkerInterface in a MyClass instance. This has some counter-intuitive consequences. One is that "inheriting in an implementation" works, and another is that construction of that base class sub-object happens down in each MyClass constructor, and more generally down in the most derived class.
Cheers & hth.,

this pointer to base class constructor?

I want to implement a derived class that should also implement an interface, that have a function that the base class can call. The following gives a warning as it is not safe to pass a this pointer to the base class constructor:
struct IInterface
{
void FuncToCall() = 0;
};
struct Base
{
Base(IInterface* inter) { m_inter = inter; }
void SomeFunc() { inter->FuncToCall(); }
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
Derived() : Base(this) {}
FuncToCall() {}
};
What is the best way around this? I need to supply the interface as an argument to the base constructor, as it is not always the dervied class that is the interface; sometimes it may be a totally different class.
I could add a function to the base class, SetInterface(IInterface* inter), but I would like to avoid that.
You shold not publish this from the constructor, as your object is not yet initialized properly at that point. In this actual situation, though, it seems to be safe, since you are publishing it only to the base class, which only stores it and does not invoke it until some point later, by which time the construction will have been finished.
However, if you want to get rid of the warning, you could use a static factory method:
struct Base
{
public:
Base() { }
void setInterface(IInterface* inter) { m_inter = inter; }
void SomeFunc() { inter->FuncToCall(); }
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
private:
Derived() : Base() {}
public:
static Derived* createInstance() {
Derived instance = new Derived();
instance->setInterface(instance);
return instance;
}
FuncToCall() {}
};
Note that the constructor of Derived is private to ensure that instantiation is done only via createInstance.
You can always defer the interface dereference:
struct IInterface
{
virtual ~IInterface();
virtual void FuncToCall() =0;
};
class Base
{
public:
virtual ~Base();
void SomeFunc() { GetInterface().FuncToCall(); }
private:
virtual IInterface& GetInterface() =0;
};
class Derived: public Base, public IInterface
{
public:
private:
virtual IInterface& GetInterface() { return *this; }
virtual void FuncToCall();
};
There is a limited set of operations that you can do (guaranteed by the standard) with a pointer to a yet uninitialized object, and storing it for further use is one of them. The compiler is probably warning as it is easy to misuse the received pointer in Base.
Beware that most uses of the pointer for other than storage will be undefined behavior, but the code above is correct.
What is quite funny is that you could get away with it by initializing it later on:
Derived::Derived(): Base()
{
this->setInter(this);
}
is fine, because all attributes have been initialized.
This way you won't have to change your whole design just to get away with the warning.
However, unless the setInter does not do anything with this apart some storage, you might access an object you did not fully initialized (so storing a hash value could be awkward).
how about:
struct IInterface
{
void FuncToCall() = 0;
IInterface* me() { return this; }
};
...
struct Derived : IInterface, Base
{
Derived() : IInterface(), Base(me()) {}
FuncToCall() {}
};
at the point we get to Base constructor IInterface is already initialized, so the call to me() is safe, and warning free
what about using protected: for IInterface* m_inter;
struct IInterface
{
virtual void FuncToCall() = 0;
};
struct Base
{
Base(IInterface* inter) { m_inter = inter; }
void SomeFunc() { m_inter->FuncToCall(); }
protected: // or `public:` since you are using `struct`
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
//Derived() : Base(this) {} // not good to use `this` in the initialization list
Derived() : Base() { m_inter = static_cast<IInterface*>(this); }
FuncToCall() {}
};