发布于 

C++杂谈002. 接口与智能指针的结合

类(对象)是C++的第一公民,类的接口继承(通过基类指针调用具体类的重载方法)是实现模块解耦的常用方法,而

比如,一个经典的继承例子,Student和Teacher都继承自Person,拥有GetName()方法。

class Person {
public:
virtual std::string GetName() const = 0;
}

class Teacher: public Person {
public:
Teacher(const std::string &name): name_(name) {}
std::string GetName() const override { return name_; }
void Teach() {}
private:
std::string name_;
}

class Student: public Person {
public:
Student(const std::string &name): name_(name) {}
std::string GetName() const override { return name_; }
void Learn() {}
private:
std::string name_;
}

如果遍历所有角色,可以直接使用基类Person指针来实现。

std::vector<Person *> CreateUsers() {
std::vector<Person *> users;
Person *one_teacher = new Teacher("ZhangSan");
users.push_back(one_teacher);

Person *one_student = new Student("XiaoMing");
users.push_back(one_student);
Person *another_student = new Student("XiaoHua");
users.push_back(another_student);

return users;
}

void PrintUsers(const std::vector<Person *> &users) {
for (user: users) {
std::cout << user->GetName() << std::endl;
}
}

int main() {
auto users = CreateUsers();
PrintUsers(users);
}

上面的代码是典型的接口调用,但是裸指针的内存管理比较麻烦,容易存在内存泄漏或者double free,这里结合智能指针来改造一下。

using PersonPtr = std::unique_ptr<Person>;

std::vector<PersonPtr> CreateUsers() {
std::vector<PersonPtr> users;
PersonPtr one_teacher = std::make_unique<Teacher>("ZhangSan");
users.push_back(one_teacher);

PersonPtr one_student = std::make_unique<Student>("XiaoMing");
users.push_back(one_student);
PersonPtr another_student = std::make_unique<Student>("XiaoHua");
users.push_back(another_student);

return users;
}

这样就可以用智能指针管理接口对应的各种实体对象了。