1

In the constructor of one of my classes I have this line :

m_Projects = std::vector<parent_project>(); //m_Projects type is std::vector<parent_project>
m_Current = nullptr; //m_Current type is parent_project*

In a function of this same class I have this line :

m_Projects.push_back(local_project(TITLE, DEMO, FILE)); //local_project class derives from parent_project class.

In a third function of this same class I have these lines :

m_Current = &m_Projects[0];

if (dynamic_cast<local_project*>(m_Current))

   SetCurrentProject(dynamic_cast<model::local_univariate::local_univariate_project*>(m_Current));

The dynamic_cast returns a null value, but as I understand the cast would be supposed to work since m_Current is a pointer to the first element of m_Projects, which is a local_project object. I think I may be missing something.

DreamTool
  • 149
  • 1
  • 15

1 Answers1

2

as I understand the cast would be supposed to work since m_Current ... is a local_project object.

What you are saying would be true if the vector was containing pointers to parent_project. But as it stores objects, parent_project copy constructor is used to copy your local_project(TITLE, DEMO, FILE) object when being inserted (push_back) in the container and then the container stores a parent_project, not a local_project. So m_Current is not a local_project anymore...

You should change m_Projects to be a std::vector<parent_project*>. Then your dynamic cast will work.

m_Projects.push_back(new local_project(TITLE, DEMO, FILE));

m_Current = m_Projects[0];

Make sure you delete the objects when clearing your container to avoid memory leaks then. Or simply use a unique_ptr or shared_ptr.

As commented by Mark Ransom, see What is object slicing?

Community
  • 1
  • 1
jpo38
  • 20,821
  • 10
  • 70
  • 151
  • Exactly so. Search for "object slicing" to understand more. – Mark Ransom Oct 20 '16 at 20:43
  • Thank you to you both. I did not think about my objects being copied. As I look closer in the debugger, I now realise it (expanding the vector shows strictly some base class objects). – DreamTool Oct 20 '16 at 20:52
  • 1
    Should probably at least mention unique ptr, that's almost certainly more likely to be correct than raw pointers because his vector currently owns the objects. – Nir Friedman Oct 20 '16 at 20:53
  • `unique_ptr` may not be enough because it doesn't handle type erase unless you pass a deleter. `shared_ptr` will handle the deleter – Bryan Chen Oct 20 '16 at 20:54
  • @Bryan Chen I don't know what you mean. Unique pointer to base works perfectly well. The type erasure is handled by the virtual destructor which is standard practice. – Nir Friedman Oct 20 '16 at 23:37
  • @jpo38 Do not suggest shared pointer, this again changes ownership semantics of original code. Original code was value, which is unique ownership. Not non ownership, and not shared ownership. – Nir Friedman Oct 20 '16 at 23:40