-1

Given the relationship of classes shown in the code below:

class Base
{
    virtual getValue() { return 0; }
};
class Derived: public Base
{
    getValue() override { return 1; }
};
class Another
{
    Base* makeClass( bool );
    void createVector();
};
Base* Another::makeClass( bool base )
{
    if( base )
    {
        return new Base();
    }
    else
    {
        return new Derived();
    }
}
void Another::createVector()
{
     std::vector<Base> vector;
     vector.emplace( *makeClass( false ) );
     std::cout << vector[0].getValue();
}

Why does it print 0 instead of 1 ? Is it converting the Derived* into a Base when added to the vector?

loki
  • 142
  • 1
  • 9
  • Which virtual function of the objects were called? How was it declared? Please share the related code. – balki Dec 12 '17 at 20:59
  • 1
    Please show the code calling makeClass, storing the response and accessing the virtual function. – ZeroUltimax Dec 12 '17 at 20:59
  • When you return a base pointer it allows you to call functions in the Base class and if they are overloaded in derived, the overloaded function will be called instead – Jake Freeman Dec 12 '17 at 21:04
  • 2
    This code is technically correct, so the only way calling a method via a `Base*` pointer would exhibit `Base` class behavior is if the method in question is not `virtual` to begin with, or is not overwritten in `Derived`. – Remy Lebeau Dec 12 '17 at 21:04
  • This was already a helpful comment, since it suggested that this function should be working as intendend (which it is). The Issue was, that i stored it in a map as `Base` which caused the behavior. I changed that to `Base*` and now it works. – loki Dec 12 '17 at 21:13
  • @loki General advice for posting questions at Stack Overflow: If it's about problems with specific code, post a [MCVE] that exactly can be used to reproduce the problem. Thank you for your attention. I'll be happy to retract my down and close vote if you consider to improve your post regarding [this](http://idownvotedbecau.se/nomcve/). – user0042 Dec 12 '17 at 21:19
  • @user0042 I edited my question. Hope it became more clear this way. – loki Dec 12 '17 at 21:40
  • @loki Possible duplicate of [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing). – user0042 Dec 12 '17 at 22:14

1 Answers1

1

"Is it converting the Derived* into a Base when added to the vector?" Yes.

In

vector.emplace( *makeClass( false ) );

*makeClass( false ) dereferences the pointer returned and slices it into a Base. This Base is stored in the vector

Recommended reading: What is object slicing?

To fix this,

 std::vector<Base *> vector; // but watch out for Cylons
 vector.emplace( makeClass( false ) );
 std::cout << vector[0]->getValue();

Or better, research std::unique_ptr and get smart pointer memory management working for you.

user4581301
  • 33,082
  • 7
  • 33
  • 54