C++ 之处理模板化基类的成员名称
问题描述
假设有下面这么一段简单的代码,其中定义了两个类模板,一个基类 Animal
,一个派生类 Dog
:
复制#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Animal {
protected:
string name_ = "animal";
};
template <typename T>
class Dog : public Animal<T> {
public:
string getName()
{
return name_;
}
};
int main(int argc, char const* argv[])
{
Dog<int> dog;
cout << dog.getName();
return 0;
}
在狗狗类中有个 getName()
方法,返回基类部分的成员 name_
,感觉看上去没什么问题,但是编译的时候却会报错:
问题解决
出现这个问题的原因在于,在 Animal<T>
被实例化之前,编译器无法得知里面是否有 name_
这个数据成员。比如我们自己全特化一个空的 Animal
,这里面就啥也没有:
复制template <>
class Animal<int> {
};
要想正确访问模板化基类中的成员,有以下三种方法:
-
使用
this
指针,比如this->name_
; -
使用
using
声明,如下述代码所示:复制
template <typename T> class Dog : public Animal<T> { public: using Animal<T>::name_; string getName() { return name_; } };
-
使用
Animal<T>::name_
显式指出成员在基类中,但是这种方法有个缺点,就是访问不了子类重写后的虚函数。
有一点需要指出的是,如果子类重写了模板化父类的虚函数,由于能在子类作用域中找到虚函数的名字,所以不需要 this
指针等方法就能调用该函数,以上~~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通