0

Suppose I have a base class Base and a derived class Derived as well as a std::vector<Base> vec(k) that is being initialised with k Base instances.

How would I go about replacing instances of Base with instances of Derived while iterating over the vector?

If the classes were not hierarchically structured like ints I could just do this:

for (auto i = vec.begin(); i != vec.end();)
{
    if (j == 3)
    {
        *i = 9;
    }
    else
    {
        ++i;
     }
}

But with derived and base classes this does not work, as this shows:

#include<iostream>
#include<vector>
#include<ostream>

class Base
{

public:

    friend std::ostream& operator<<(std::ostream& o, Base& e)
    {
        return o << e.get_repr();
    }

private:

    virtual std::string get_repr()
    {
        return repr;
    }

private:

    std::string repr = "B";
};

class Derived: public Base
{

private:

    std::string get_repr()
    {
        return repr;
    }

private:

    std::string repr = "D";
};






int main()
{

    std::vector<Base> vec(5);

    int j = 0;
    for (auto i = vec.begin(); i != vec.end(); ++j)
    {
        if (j == 3)
    {
        *i = Derived();
    }
    else
    {
        ++i;
    }
    }

    for (auto i = vec.begin(); i != vec.end(); ++i)
    {
        std::cout << *i << ' ';
    }
    std::cout << std::endl;

}

the output being:

B B B B B

So how can I replace the Base-instance with a Derived-instance?

Edit

I changed the cell contents to pointers, as suggested in the comments. I did it like this:

int main()
{

    std::vector<Base*> vec(5);

    int j = 0;
    for (auto i = vec.begin(); i != vec.end(); ++j)
    {
        if (j == 3)
        {
            *i = new Derived();
        }
        else
        {
            *i = new Base();
            ++i;
        }
    }

    for (auto i = vec.begin(); i != vec.end(); ++i)
    {
        std::cout << **i << ' ';
    }
    std::cout << std::endl;

}

but I am still getting B B B B B... why?

Community
  • 1
  • 1
lo tolmencre
  • 3,804
  • 3
  • 30
  • 60
  • 1
    You can't since you have concrete `Base` objects in your vector, any attempt would result to object slicing. – 101010 May 04 '16 at 13:21
  • 1
    Change the vector to `std::vector` or `std::vector>` and then use `static_cast` (in the former case) to cast to derived class – sjrowlinson May 04 '16 at 13:23
  • I thought vector stored only pointers in its cells anyway, placing the objects in the ram...? – lo tolmencre May 04 '16 at 15:59
  • @ArchbishopOfBanterbury I also tried implementing your solution, but I am still getting the same result. I edited the question. – lo tolmencre May 04 '16 at 16:11
  • 1
    @lotolmencre `get_repr()` has `private` access in your class `Base` meaning it can't be overridden in `Derived`. Change this access to `protected`. – sjrowlinson May 04 '16 at 16:15
  • @ArchbishopOfBanterbury Oh, I see, yes. But actually I can do `Base* b = new Base(); b = new Derived(); std::cout << *b << std::endl;` giving me `D`, without changing `get_repr()` to `protected`. But when doing the same thing in the loop (with changing `get_repr()` to `protected`) the result is still `B B B B B`... Which I find kinda puzzling. – lo tolmencre May 04 '16 at 16:28

0 Answers0