模板类扩展疑问:List<T>子类MyList实现remove_last()及后续需求
扩展链表类的两个实现方案
我来帮你搞定这两个需求,直接上代码和关键细节——都是模板类开发里容易踩坑的点:
第一部分:子类化List<T>实现remove_last()
因为List<T>是模板类,咱们的子类也得是模板类,继承的时候要注意语法细节,还要确保能正确访问父类的成员方法(模板继承里编译器不会自动查找父类的依赖名称,得加this->前缀)。
假设父类List<T>提供了基础的迭代器接口(end()、erase())和size()方法,实现代码如下:
#include <iterator> template <typename T> class MyList : public List<T> { public: void remove_last() { // 先判空,避免空链表操作出错 if (this->size() == 0) { return; } // 尾后迭代器退一位就是最后一个元素的迭代器 auto last_iter = --this->end(); this->erase(last_iter); } };
如果父类没给迭代器,只有按索引访问的get()和remove(int)方法,那改成这样:
template <typename T> class MyList : public List<T> { public: void remove_last() { if (this->size() == 0) { return; } // 最后一个元素的索引是size()-1 this->remove(this->size() - 1); } };
关键注意点:
- 模板子类必须和父类保持模板参数一致,继承时写
public List<T> - 访问父类的
size()、erase()这些方法时,必须加this->,不然编译器可能找不到 - 一定要先检查链表是否为空,防止越界
第二部分:仅移除最后一个是单词的元素
这里我把“单词”定义成非空的std::string,且所有字符都是字母。咱们新增一个remove_last_if_word()方法,这样不破坏原有remove_last()的功能,更符合单一职责。
代码实现:
#include <string> #include <cctype> template <typename T> class MyList : public List<T> { public: void remove_last() { if (this->size() == 0) { return; } auto last_iter = --this->end(); this->erase(last_iter); } void remove_last_if_word() { if (this->size() == 0) { return; } // 获取最后一个元素的引用 T& last_elem = *(--this->end()); // 编译期判断是否是string类型,非string类型直接跳过 if constexpr (std::is_same_v<T, std::string>) { bool is_valid_word = !last_elem.empty(); // 遍历每个字符,检查是否都是字母 for (char c : last_elem) { // 转成unsigned char避免isalpha处理负数值的未定义行为 if (!std::isalpha(static_cast<unsigned char>(c))) { is_valid_word = false; break; } } // 如果是有效单词,调用remove_last()移除 if (is_valid_word) { remove_last(); } } } };
如果父类用索引访问,对应的版本:
#include <string> #include <cctype> template <typename T> class MyList : public List<T> { public: void remove_last() { if (this->size() == 0) { return; } this->remove(this->size() - 1); } void remove_last_if_word() { if (this->size() == 0) { return; } T& last_elem = this->get(this->size() - 1); if constexpr (std::is_same_v<T, std::string>) { bool is_valid_word = !last_elem.empty(); for (char c : last_elem) { if (!std::isalpha(static_cast<unsigned char>(c))) { is_valid_word = false; break; } } if (is_valid_word) { remove_last(); } } } };
关键注意点:
- 用
if constexpr做编译期类型判断,这样非string类型的MyList实例化时,不会编译string相关的代码,避免报错 - 检查字符时要转成
unsigned char,因为std::isalpha对负数值的处理是未定义行为(比如某些编码下的字符可能是负数) - 先判断字符串非空,再检查每个字符,避免空字符串被误判
内容的提问来源于stack exchange,提问作者mhm
相关产品推荐
相关产品推荐

