error C2259: 'class' : cannot instantiate abstract class - c++

Now, I understand a good amount about abstract classes at this point, however, I was recently trying to use an abstract class to create a virtual function to receive messages and then another class that has an std::vector of smart pointers to this class, but then I got the error C2259. (yes, I did look it up here)
Side Note:
I also have recently been reading up a good amount on smart pointers since they are almost (if not always) mentioned in every question relating to pointers. So I decided to try and implement them for the first time, so my problem might actually be because of my improper use of smart pointers.
Anyways, here is the pure abstract class itself --
//Component.h
namespace rpg
{
class Component
{
public:
virtual void Receive(rpg::Message message) = 0;
Component();
virtual ~Component();
};
And here is the class that gets the error trying to use the pure abstract class.
//ContainerObject.h
#include <vector>
#include <memory>
#include "Component.h"
namespace rpg
{
class ContainerObject
{
private:
//Create short name for a vector of smart pointers to the pure abstract class
typedef std::vector<std::shared_ptr<rpg::Component>> ComponentList;
//Create array of Components (std::vector).
ComponentList myComponents;
public:
//Send message to all Components in array (std::vector)
void Send(rpg::Message message)
{
if(myComponents.size() > 0)
{
for(int i = 0; i < myComponents.size(); i++)
{
if(myComponents[i] != NULL)
{
myComponents[i]->Receive(message);
}
}
}
} // end of Send()
//Add new Component to array (std::vector)
void AddComponentToMessageList(rpg::Component& component)
{
myComponents.push_back(std::make_shared<rpg::Component>(component));
}
ContainerObject();
~ContainerObject();
};
} //namespace rpg
First off, I am trying to practice better code organization (which I am learning some here <-- also where I got most of this design) and I like the layout if I can keep it. I also read up some on pure abstract classes here and I saw near the bottom of the page that they still declare a list of pointers to objects of the pure abstract class so I am pretty sure I can use it this way, so why am I getting error C2295 and how can I fix it? Where might I be instantiating it and what causes it to be instantiated?
(I think the term instantiate is probably the part the really confuses me which is why I also asked what causes it, so if you could also include that in your answer it would be much appreciated. (And I did google its definition; I'm still confused))

void AddComponentToMessageList(std::shared_ptr<rpg::Component>& component)
{
myComponents.push_back(component);
}
Try it that way and create the object using std::make_shared before you call AddComponentToMessageList function. I have never tried to instantiate a class with a smart pointer using the copy constructor. From the first sight it looks like it should work, but you never know.
Another note. Prefer interfaces over abstract class. Meaning create an IComponent interface that will look like this:
class IComponent
{
public:
virtual void Receive(rpg::Message message) = 0;
virtual ~Component() { };
};
Then have your classes implement this interface. Obviously your vector needs to change, become a container of std::shared_ptr.
Now I also noticed that you cannot create an abstract class, regardless whether through "new", on the stack, or std::make_shared.

You are trying to instantiate Component when you call make_shared in this line:
myComponents.push_back(std::make_shared<rpg::Component>(component));
make_shared tries to execute new rpg::Component(component) which fails because Component is abstract.

Related

Defining a class with an vector of interfaces [duplicate]

Having spent quite some time developping in C#, I noticed that if you declare an abstract class for the purpose of using it as an interface you cannot instantiate a vector of this abstract class to store instances of the children classes.
#pragma once
#include <iostream>
#include <vector>
using namespace std;
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
class FunnyContainer
{
private:
std::vector <IFunnyInterface> funnyItems;
};
The line declaring the vector of abstract class causes this error in MS VS2005:
error C2259: 'IFunnyInterface' : cannot instantiate abstract class
I see an obvious workaround, which is to replace IFunnyInterface with the following:
class IFunnyInterface
{
public:
virtual void IamFunny()
{
throw new std::exception("not implemented");
}
};
Is this an acceptable workaround C++ wise ?
If not, is there any third party library like boost which could help me to get around this ?
Thank you for reading this !
Anthony
You can't instantiate abstract classes, thus a vector of abstract classes can't work.
You can however use a vector of pointers to abstract classes:
std::vector<IFunnyInterface*> ifVec;
This also allows you to actually use polymorphic behaviour - even if the class wasn't abstract, storing by value would lead to the problem of object slicing.
You can't create a vector of an abstract class type because you cannot create instances of an abstract class, and C++ Standard Library containers like std::vector store values (i.e. instances). If you want to do this, you will have to create a vector of pointers to the abstract class type.
Your workround would not work because virtual functions (which is why you want the abstract class in the first place) only work when called through pointers or references. You cannot create vectors of references either, so this is a second reason why you must use a vector of pointers.
You should realise that C++ and C# have very little in common. If you are intending to learn C++, you should think of it as starting from scratch, and read a good dedicated C++ tutorial such as Accelerated C++ by Koenig and Moo.
In this case we can't use even this code:
std::vector <IFunnyInterface*> funnyItems;
or
std::vector <std::tr1::shared_ptr<IFunnyInterface> > funnyItems;
Because there is no IS A relationship between FunnyImpl and IFunnyInterface and there is no implicit convertion between FUnnyImpl and IFunnyInterface because of private inheritance.
You should update your code as follows:
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: public IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
The traditional alternative is to use a vector of pointers, like already noted.
For those who appreciate, Boost comes with a very interesting library: Pointer Containers which is perfectly suited for the task and frees you from the various problems implied by pointers:
lifetime management
double dereferencing of iterators
Note that this is significantly better than a vector of smart pointers, both in terms of performance and interface.
Now, there is a 3rd alternative, which is to change your hierarchy. For better insulation of the user, I have seen a number of times the following pattern used:
class IClass;
class MyClass
{
public:
typedef enum { Var1, Var2 } Type;
explicit MyClass(Type type);
int foo();
int bar();
private:
IClass* m_impl;
};
struct IClass
{
virtual ~IClass();
virtual int foo();
virtual int bar();
};
class MyClass1: public IClass { .. };
class MyClass2: public IClass { .. };
This is quite straightforward, and a variation of the Pimpl idiom enriched by a Strategy pattern.
It works, of course, only in the case where you do not wish to manipulate the "true" objects directly, and involves deep-copy. So it may not be what you wish.
Because to resize a vector you need to use the default constructor and the size of the class, which in turn requires it to be concrete.
You can use a pointer as other suggested.
std::vector will try to allocate memory to contain your type. If your class is purely virtual, the vector cannot know the size of the class it will have to allocate.
I think that with your workaround, you will be able to compile a vector<IFunnyInterface> but you won't be able to manipulate FunnyImpl inside of it. For example if IFunnyInterface (abstract class) is of size 20 (i dont really know) and FunnyImpl is of size 30 because it has more members and code, you will end up trying to fit 30 into your vector of 20
The solution would be to allocate memory on the heap with "new" and store pointers in vector<IFunnyInterface*>
I think that the root cause of this really sad limitation is the fact that constructors can not virtual. Thereof compiler can not generate code which copy the object without knowing its time in the compile time.

How to include base class without implementing pure virtual functions? [duplicate]

Having spent quite some time developping in C#, I noticed that if you declare an abstract class for the purpose of using it as an interface you cannot instantiate a vector of this abstract class to store instances of the children classes.
#pragma once
#include <iostream>
#include <vector>
using namespace std;
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
class FunnyContainer
{
private:
std::vector <IFunnyInterface> funnyItems;
};
The line declaring the vector of abstract class causes this error in MS VS2005:
error C2259: 'IFunnyInterface' : cannot instantiate abstract class
I see an obvious workaround, which is to replace IFunnyInterface with the following:
class IFunnyInterface
{
public:
virtual void IamFunny()
{
throw new std::exception("not implemented");
}
};
Is this an acceptable workaround C++ wise ?
If not, is there any third party library like boost which could help me to get around this ?
Thank you for reading this !
Anthony
You can't instantiate abstract classes, thus a vector of abstract classes can't work.
You can however use a vector of pointers to abstract classes:
std::vector<IFunnyInterface*> ifVec;
This also allows you to actually use polymorphic behaviour - even if the class wasn't abstract, storing by value would lead to the problem of object slicing.
You can't create a vector of an abstract class type because you cannot create instances of an abstract class, and C++ Standard Library containers like std::vector store values (i.e. instances). If you want to do this, you will have to create a vector of pointers to the abstract class type.
Your workround would not work because virtual functions (which is why you want the abstract class in the first place) only work when called through pointers or references. You cannot create vectors of references either, so this is a second reason why you must use a vector of pointers.
You should realise that C++ and C# have very little in common. If you are intending to learn C++, you should think of it as starting from scratch, and read a good dedicated C++ tutorial such as Accelerated C++ by Koenig and Moo.
In this case we can't use even this code:
std::vector <IFunnyInterface*> funnyItems;
or
std::vector <std::tr1::shared_ptr<IFunnyInterface> > funnyItems;
Because there is no IS A relationship between FunnyImpl and IFunnyInterface and there is no implicit convertion between FUnnyImpl and IFunnyInterface because of private inheritance.
You should update your code as follows:
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: public IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
The traditional alternative is to use a vector of pointers, like already noted.
For those who appreciate, Boost comes with a very interesting library: Pointer Containers which is perfectly suited for the task and frees you from the various problems implied by pointers:
lifetime management
double dereferencing of iterators
Note that this is significantly better than a vector of smart pointers, both in terms of performance and interface.
Now, there is a 3rd alternative, which is to change your hierarchy. For better insulation of the user, I have seen a number of times the following pattern used:
class IClass;
class MyClass
{
public:
typedef enum { Var1, Var2 } Type;
explicit MyClass(Type type);
int foo();
int bar();
private:
IClass* m_impl;
};
struct IClass
{
virtual ~IClass();
virtual int foo();
virtual int bar();
};
class MyClass1: public IClass { .. };
class MyClass2: public IClass { .. };
This is quite straightforward, and a variation of the Pimpl idiom enriched by a Strategy pattern.
It works, of course, only in the case where you do not wish to manipulate the "true" objects directly, and involves deep-copy. So it may not be what you wish.
Because to resize a vector you need to use the default constructor and the size of the class, which in turn requires it to be concrete.
You can use a pointer as other suggested.
std::vector will try to allocate memory to contain your type. If your class is purely virtual, the vector cannot know the size of the class it will have to allocate.
I think that with your workaround, you will be able to compile a vector<IFunnyInterface> but you won't be able to manipulate FunnyImpl inside of it. For example if IFunnyInterface (abstract class) is of size 20 (i dont really know) and FunnyImpl is of size 30 because it has more members and code, you will end up trying to fit 30 into your vector of 20
The solution would be to allocate memory on the heap with "new" and store pointers in vector<IFunnyInterface*>
I think that the root cause of this really sad limitation is the fact that constructors can not virtual. Thereof compiler can not generate code which copy the object without knowing its time in the compile time.

Ranged based for loop not compiling with vector of abstract class [duplicate]

Having spent quite some time developping in C#, I noticed that if you declare an abstract class for the purpose of using it as an interface you cannot instantiate a vector of this abstract class to store instances of the children classes.
#pragma once
#include <iostream>
#include <vector>
using namespace std;
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
class FunnyContainer
{
private:
std::vector <IFunnyInterface> funnyItems;
};
The line declaring the vector of abstract class causes this error in MS VS2005:
error C2259: 'IFunnyInterface' : cannot instantiate abstract class
I see an obvious workaround, which is to replace IFunnyInterface with the following:
class IFunnyInterface
{
public:
virtual void IamFunny()
{
throw new std::exception("not implemented");
}
};
Is this an acceptable workaround C++ wise ?
If not, is there any third party library like boost which could help me to get around this ?
Thank you for reading this !
Anthony
You can't instantiate abstract classes, thus a vector of abstract classes can't work.
You can however use a vector of pointers to abstract classes:
std::vector<IFunnyInterface*> ifVec;
This also allows you to actually use polymorphic behaviour - even if the class wasn't abstract, storing by value would lead to the problem of object slicing.
You can't create a vector of an abstract class type because you cannot create instances of an abstract class, and C++ Standard Library containers like std::vector store values (i.e. instances). If you want to do this, you will have to create a vector of pointers to the abstract class type.
Your workround would not work because virtual functions (which is why you want the abstract class in the first place) only work when called through pointers or references. You cannot create vectors of references either, so this is a second reason why you must use a vector of pointers.
You should realise that C++ and C# have very little in common. If you are intending to learn C++, you should think of it as starting from scratch, and read a good dedicated C++ tutorial such as Accelerated C++ by Koenig and Moo.
In this case we can't use even this code:
std::vector <IFunnyInterface*> funnyItems;
or
std::vector <std::tr1::shared_ptr<IFunnyInterface> > funnyItems;
Because there is no IS A relationship between FunnyImpl and IFunnyInterface and there is no implicit convertion between FUnnyImpl and IFunnyInterface because of private inheritance.
You should update your code as follows:
class IFunnyInterface
{
public:
virtual void IamFunny() = 0;
};
class FunnyImpl: public IFunnyInterface
{
public:
virtual void IamFunny()
{
cout << "<INSERT JOKE HERE>";
}
};
The traditional alternative is to use a vector of pointers, like already noted.
For those who appreciate, Boost comes with a very interesting library: Pointer Containers which is perfectly suited for the task and frees you from the various problems implied by pointers:
lifetime management
double dereferencing of iterators
Note that this is significantly better than a vector of smart pointers, both in terms of performance and interface.
Now, there is a 3rd alternative, which is to change your hierarchy. For better insulation of the user, I have seen a number of times the following pattern used:
class IClass;
class MyClass
{
public:
typedef enum { Var1, Var2 } Type;
explicit MyClass(Type type);
int foo();
int bar();
private:
IClass* m_impl;
};
struct IClass
{
virtual ~IClass();
virtual int foo();
virtual int bar();
};
class MyClass1: public IClass { .. };
class MyClass2: public IClass { .. };
This is quite straightforward, and a variation of the Pimpl idiom enriched by a Strategy pattern.
It works, of course, only in the case where you do not wish to manipulate the "true" objects directly, and involves deep-copy. So it may not be what you wish.
Because to resize a vector you need to use the default constructor and the size of the class, which in turn requires it to be concrete.
You can use a pointer as other suggested.
std::vector will try to allocate memory to contain your type. If your class is purely virtual, the vector cannot know the size of the class it will have to allocate.
I think that with your workaround, you will be able to compile a vector<IFunnyInterface> but you won't be able to manipulate FunnyImpl inside of it. For example if IFunnyInterface (abstract class) is of size 20 (i dont really know) and FunnyImpl is of size 30 because it has more members and code, you will end up trying to fit 30 into your vector of 20
The solution would be to allocate memory on the heap with "new" and store pointers in vector<IFunnyInterface*>
I think that the root cause of this really sad limitation is the fact that constructors can not virtual. Thereof compiler can not generate code which copy the object without knowing its time in the compile time.

Identifying which Base Class shared_ptr has been passed into a Super Class shared_ptr vector

I am working on a C++ project, specifically implementing a shunting yard algorithm.
I have a function that creates a vector of shared_ptr's of type super class, but the classes that are being pushed into this vector are all base class shared_ptrs.
I then need to take this vector and pass it into another function and carry out different logic for each element of the vector in a for loop. The logic that I carry out, however, depends on which base class is present in each element of the vector.
So basically what I don't know is how to identify which type of base class is in each element of the vector. When I debug they are all coming out as type super-class.
So generally I'd like to do something like this:
if(vectorElement == baseClass)
{
//do some logic
}
Or if there is some different method of carrying this out which I'm missing I'd be interested in carrying that out.
There are many solutions to your problem, frankly is the almost most common problem in OOP.
The most obvious is the virtual function doing different things in different classes:
class SuperClass {
public:
virtual void doSomething(/*someArgsIfNeeded*/) {
// some base implementation, possible empty
// or just use pure virtual function here
}
};
class SubClass : public SuperClass {
public:
virtual void doSomething(/*someArgsIfNeeded*/) {
// some base implementation
}
};
Then use it as follows:
int SomeArgs;
std::vector<std::shared_ptr<SuperClass>> objects;
for (auto it = objects.begin(); it != objects.end(); ++i)
it->doSomething(/*someArgsIfNeeded*/);
Other more sophisticated solution is to use visitor pattern.
It is considered a bad practice to use casting (dynamic_cast), so always search for more OO solutions than casting, like these two I presented above.
Off the top of my head, a simple solution would be to have a function in the base class, that returns an int signifying which class it is. And in each of the derived classes, override this function to return different values. You could use that value to determine which class is being stored in the vector
Edit: And Generally class specific details are to be left in the class, which is the point of polymorphism. Try to do the derived class specific calculations as an overided member function within each class, and use that just to fetch the value forgoing the need for large for loops (for each new derived class) outside.

Clone abstract base class (without meddling with derived)

I'm experiencing a challenging problem, which has not been solvable - hopefully until now. I'm developing my own framework and therefore trying to offer the user flexibility with all the code complexity under the hood.
First of all I have an abstract base class which users can implement, obviously simplified:
class IStateTransit
{
public:
bool ConnectionPossible(void) = 0;
}
// A user defines their own class like so
class MyStateTransit : public IStateTransit
{
public:
bool ConnectionPossible(void){ return true; }
}
Next, I define a factory class. Users can register their own custom state transit objects and refer to them later by simply using a string identifier they have chosen:
class TransitFactory : public Singleton<TransitFactory>
{
public:
template<typename T> void RegisterStateTransit(const string& name)
{
// If the transit type is not already registered, add it.
if(transits.find(name) == transits.end())
{
transits.insert(pair<string, IStateTransit*>(name, new T()));
};
}
IStateTransit* TransitFactory::GetStateTransit(const string& type) const
{
return transits.find(type)->second;
};
private:
map<string, IStateTransit*> transits;
}
Now the problem is (probably obviously) that whenever a user requests a transit by calling GetStateTransit the system currently keeps returning the same object - a pointer to the same object that is. I want to change this.
PROBLEM: How can I return a new (clone) of the original IStateTransit object without the user having to define their own copy constructor or virtual constructor. Ideally I would somehow like the GetStateTransit method to be able to cast the IStateTransit object down to the derived type it is at runtime and return a clone of that instance. The biggest hurdle is that I do not want the user to have to implement any extra (and probably complex) methods.
4 hours of Googling and trying has led me nowhere. The one who has the answer is a hero!
The problem is that you don't have the type information to perform the clone as you only have a pointer to base class type and no knowledge as to what derived types have been implemented and are available.
I think there's a reason that 4 hours of googling haven't turned anything up. If you want IStateTransit to be cloneable you have to have an interface where the derived class implementer provides some sort of clone method implementation.
I'm sorry if this isn't what you wanted to hear.
However, implementing a clone method shouldn't be a big burden. Only the class implementor knows how a class can be copied, given a correct copy constructor, clone can be implemented for a leaf-node class like this:
Base* clone() const
{
return new MyType(*this);
}
You could even macro-alize it; although I wouldn't.
If I understand the problem correctly, you shouldn't insert new T -s into the map, but rather objects that create new T-s.
struct ICreateTransit
{
virtual ~ICreateTransit() {}
virtual IStateTransite* create() const = 0;
};
template <class T>
struct CreateTransit: public ICreateTransit
{
virtual IStateTransit* create() const { return new T(); }
};
And now insert:
transits.insert(pair<string, ICreateTransit*>(name, new CreateTransit<T>()));
And retrieve "copies" with:
return transits.find(type)->second->create(); //hopefully with error handling
It shouldn't be impossible to modify StateTransit<T> so it holds a T of which to make copies of, should the default one not do.
I think the general name for techniques like this is called "type erasure" (derived types "remember" particular types, although the base class is unaware of those).
This problem to me sounds that the abstract factory pattern might be of help. Using this pattern the libraries client can define how your framework builds its types. The client can inject his own subclass of the factory into the framework and define there what types should be build.
What you need is (additionaly)
A base class for the factory
As a client: Derive a concrete factory
A way to inject (as a client) a subtype of the factory into the framework
Call the factory metods to create new types.
Does this help you?