Reputation: 7681
I am building a container type which holds pointers to a class heirachy. My issue is that I can't seem to change an element using something like:
container[0] = x
Here's a minimal example that reproduces my problem.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Animal {
protected:
std::string noise = "None";
public:
Animal() = default;
virtual ~Animal() = default;
virtual std::string getNoise() {
return noise;
}
};
class Duck : public Animal {
public:
Duck() {
noise = "Quack!";
}
};
class Dog : public Animal {
public:
Dog() {
noise = "Bark!";
}
};
class Cat : public Animal {
public:
Cat() {
noise = "Me-thefuck-ow!";
}
Cat& operator=(Cat const& other) {
noise = other.noise;
return *this;
}
};
typedef std::shared_ptr<Animal> AnimalPtr;
class AnimalsContainer {
public:
std::vector<AnimalPtr> animals;
AnimalPtr front;
Duck duck;
Dog dog;
AnimalsContainer() {
animals.push_back(std::make_unique<Animal>(duck));
animals.push_back(std::make_unique<Animal>(dog));
front = animals[0];
}
AnimalsContainer(AnimalsContainer& animalsContainer) = default;
~AnimalsContainer() = default;
AnimalsContainer& operator=(const AnimalsContainer& animalsContainer) = default;
AnimalsContainer& operator=(AnimalsContainer&& animalsContainer) = default;
AnimalPtr operator[](int index){
return animals[index];
}
};
int main() {
AnimalsContainer animalsContainer;
cout << animalsContainer[0]->getNoise() << endl;
Cat cat;
animalsContainer[0] = std::make_unique<Animal>(cat);
cout << animalsContainer[0]->getNoise() << endl;
return 0;
}
This outputs:
Quack!
Quack!
Where I want:
Quack!
Meow!
Upvotes: 1
Views: 56
Reputation: 29985
Here:
AnimalPtr operator[](int index) {
return animals[index];
}
You return by value, then the copy is assigned a new value. You are supposed to return a reference:
AnimalPtr& operator[](int index) {
return animals[index];
}
Also you probably meant to use make_shared
instead of make_unique
in all cases.
Upvotes: 3