4

I have an abstract class element and a child class elasticFrame :

class element
{
public:
    virtual Matrix getStiffness() = 0;
protected:
    Matrix K;
};


class elasticFrame3d:public element
{
public:
    elasticFrame3d(double E, double G);
    virtual Matrix getStiffness();
virtual Matrix getTransform();
private:
    double E, G;
};

what I want is to make a map like this:

map<int, element> elementMap;

but when I get this error:

error C2259: 'element' : cannot instantiate abstract class

is it even possible to do this? if yes how?

Alexander1991
  • 217
  • 5
  • 13

2 Answers2

6

You won't be able to create a value of type element as it has abstract function. If you want to store objects of a type derived from element, you'll need to store a suitable pointer or reference to these objects. You can, e.g., use std::unique_ptr<element> or std::shared_ptr<element> (you need to include #include <memory>) and allocate the concrete objects in a suitable memory area.

That is, you would use something like this:

std::map<int, std::unique_ptr<element>> elementMap;
elementMap[17] = std::unique_ptr<element>(new elasticFrame3D(3.14, 2.71));

BTW, you are using an unusal naming convention: when using CamelCase types are normally written with a capital letter and objects using a lowercase initial letter.

BDL
  • 21,052
  • 22
  • 49
  • 55
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • thank you so much for your quick response,would you please explain more I don't understand what do you mean by _std::unique_ptr_ – Alexander1991 Aug 23 '14 at 18:53
  • One reason why you cannot do this: If you were accessing your map using the `[]` operator, and supplied a key that is not currently in the map, std::map will attempt to construct a value of value_type referenced by that key. As key_type is abstract, this cannot work. – Sir Digby Chicken Caesar Aug 23 '14 at 18:56
  • @SirDigbyChickenCaesar: I don't understand what you mean? The key tpye happens to be `int`. When an object doesn't exist, a default constructed `std::unique_ptr` will be created. Well, yes, a `std::unique_ptr` may not point at anything... – Dietmar Kühl Aug 23 '14 at 19:01
  • 1
    AH, I thought you meant to wrap the std::map in a unique ptr and not the value_type. DERP. My statement was merely referring to why you cannot do the ORIGINAL approach. Sorry for not being clear. – Sir Digby Chicken Caesar Aug 23 '14 at 19:03
  • 1
    @Alexander1991: `std::unique_ptr` is a class template defined by the standard C++ library (it is declared in ``). It hold a pointer to an object of type `T` and it `delete`s the pointer when it destroyed itself. In theory, you could just store `element*` in your map but when doing so you are setting yourself up for a memory leak. By using a smart pointer like `std::unique_ptr` or `std::shared_ptr`. Since it more lightweight and modelling strict ownership, I think `std::unique_ptr` is preferable. – Dietmar Kühl Aug 23 '14 at 19:04
-1

Pointers!

Declaration:
map<int, element*> elementMap;

Use:

elasticFrame3d thing = elasticFrame3d(1,1);
elementMap[0] = &thing;
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135