Reputation: 312
I have been attempting to create a dynamic data structure to hold a number of objects of different classes, all of which derive from the same base class. I have found advice in may places that this can be done with a vector of shared pointers. However I cannot get this to work. Code is as follows:
class ElementDetail
{
public:
virtual void* getData() = 0;
};
class TypecodeDetail : ElementDetail
{
public:
TypecodeDetail(uint32_t typecode) : _typeCode(typecode) {}
void* getData();
private:
uint32_t _typeCode{};
};
int main()
{
std::vector<std::shared_ptr<ElementDetail>> details;
details.push_back(std::make_shared<TypecodeDetail>());
}
This gives an error on push_back:
Error (active) E0304 no instance of overloaded function matches the argument list argument types are:
(std::shared_ptr<TypecodeDetail>)
object type is:std::vector<std::shared_ptr<ElementDetail>, std::allocator<std::shared_ptr<ElementDetail>>>
I have literally copied this code from answers to a number of similar questions that I searched, yet it does not work. Can anyone tell me why? Is what I am attempting possible?
Upvotes: -2
Views: 127
Reputation: 1845
To answer your question: yes, it is possible (and advisable not to use new
/delete
).
There are several issues with your code:
TypecodeDetail
by calling std::make_shared<TypecodeDetail>()
. However, as you defined a constructor taking an integer, there is no default constructor generated by the compiler. So, either you call the constructor with an integer value, or you have to define the default constructor (for instance with TypecodeDetail() = default;
)Try this:
#include <cstdint>
#include <vector>
#include <memory>
class ElementDetail
{
public:
virtual void* getData() = 0;
};
class TypecodeDetail : public ElementDetail
{
public:
TypecodeDetail(uint32_t typecode) : _typeCode(typecode) {}
void* getData() { return nullptr; }
private:
uint32_t _typeCode{};
};
int main()
{
std::vector<std::shared_ptr<ElementDetail>> details;
details.push_back(std::make_shared<TypecodeDetail>(35));
}
Upvotes: 5
Reputation: 312
Solved in comments. If anyone else is struggling, the issue is that class inheritance is private by default and needs to be made explicitly public. So in this case:
class TypecodeDetail : ElementDetail
should have been
class TypecodeDetail : public ElementDetail
Upvotes: 0
Reputation: 409422
The smart pointers are mimicking actual pointers in almost all ways. Including handling polymorphism through pointers to a base class.
So to answer your question: Yes, that will work.
The error you get is because you try to default-construct a TypecodeDetail
object, which doesn't have a default constructor. You need to pass the argument needed by the TypecodeDetail
constructor:
details.push_back(std::make_shared<TypecodeDetail>(123)); // For example
There are also other problems, as mentioned in the comments. The private inheritance being the main one.
Upvotes: 2