I have been reading around and am struggling to understand and get this working.
I have a base class Person, which Teacher & Student inherit from. I want to store them both inside of a vector of type "Person". I have tried a few things. However, I keep getting pages of errors, and I am struggling to understand them.
This current code compiled with g++ -std=c++17 test.cpp is giving me:
Undefined symbols for architecture x86_64: "Person::~Person()", referenced from: Teacher::~Teacher() in test-9423bf.o Student::~Student() in test-9423bf.o ld: symbol(s) not found for architecture x86_64 Would appreciate any tips and good references on c++ features written simply.
#include <iostream> #include <vector> #include <memory> class Person { public: virtual void printName() = 0; virtual ~Person() = 0; }; class Teacher : public Person { public: void printName() { std::cout << "Hello My Name is Teacher" << std::endl; } ~Teacher() {} }; class Student : public Person { public: void printName() { std::cout << "Hello My Name Is Student" << std::endl; } ~Student() {} }; //Capturing the raw pointer and letting it go out of scope template<typename Person, typename Teacher> std::unique_ptr<Person> static_unique_pointer_cast (std::unique_ptr<Teacher>&& old){ return std::unique_ptr<Person>{static_cast<Person*>(old.release())}; //conversion: unique_ptr<FROM>->FROM*->TO*->unique_ptr<TO> } auto main() -> int { auto t1 = std::make_unique<Teacher>(); auto t2 = std::make_unique<Teacher>(); auto t3 = std::make_unique<Teacher>(); auto s1 = std::make_unique<Student>(); auto s2 = std::make_unique<Student>(); auto s3 = std::make_unique<Student>(); std::vector<std::unique_ptr<Person>> v; // v.push_back(static_unique_pointer_cast<Person>(std::move(s1))); auto foo = static_unique_pointer_cast<Person>(std::move(s1)); // std::vector<std::unique_ptr<Person>> ve = { // std::move(t1), // std::move(t2), // std::move(t3), // std::move(s1), // std::move(s2), // std::move(s3) // }; return 0; } Edit: I got it working by changing base class destructor to default.
I now have this:
std::vector<std::unique_ptr<Person>> v; v.push_back(static_unique_pointer_cast<Person>(std::move(s1))); v.push_back(static_unique_pointer_cast<Person>(std::move(s1))); for (auto item: v) { item->printName(); } but I am getting the following error:
error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<Person, std::__1::default_delete<Person> >' for (auto item: v) { edit 2:
The above works when I use:
for (auto &&item: v) { item->printName(); } Could someone explain this to me? The vector holds unique pointers (that were once an rvalue (specifically exrvalue) but now they aren't. Why do I need to use auto &&?
= defaultinstead of= 0;.