【发布时间】:2019-07-10 02:20:13
【问题描述】:
我一直在阅读并且正在努力理解并使其正常工作。
我有一个基类 Person,Teacher & Student 继承自它。我想将它们都存储在“Person”类型的向量中。我已经尝试了几件事。但是,我不断收到错误页面,我很难理解它们。
当前代码用 g++ -std=c++17 test.cpp 编译 正在给我:
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
非常感谢任何关于简单编写的 c++ 功能的提示和良好参考。
#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;
}
编辑:我通过将基类析构函数更改为默认值来使其工作。
我现在有了这个:
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();
}
但我收到以下错误:
error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<Person, std::__1::default_delete<Person> >'
for (auto item: v) {
编辑 2:
以上方法在我使用时有效:
for (auto &&item: v) {
item->printName();
}
有人可以向我解释一下吗?该向量包含唯一的指针(曾经是一个右值(特别是 exrvalue),但现在它们不是了。为什么我需要使用 auto &&?
【问题讨论】:
-
派生类型的析构函数将尝试调用基类型的析构函数。不要让它纯粹是虚拟的。使用
= default而不是= 0;。 -
或者为你的纯虚析构函数提供一个类外定义。
-
你不能复制 unique_ptr's 这是它试图用 'for (auto item: v)' 做的事情。最好使用像 ''for (const auto& item: v) 这样的 const ref
标签: c++ c++17 unique-ptr