C++模板类编译报错:派生类无法访问基类protected成员val
为什么模板派生类无法访问基类的protected成员
val? 你碰到的这个问题,本质是C++模板继承中的依赖名称查找规则在搞鬼。虽然从继承关系上来说,派生类确实有权访问基类的protected成员,但模板场景下的规则和普通非模板继承不一样。
问题根源
当你的派生类SqrNum<T>继承自模板基类Num<T>时,编译器在解析SqrNum<T>的成员函数(比如getval())时,还不知道模板参数T的具体类型,因此它不会默认去基类Num<T>中查找未加限定的名称val——编译器会把val当成一个当前作用域的普通变量,自然就找不到它了。
而在非模板继承的场景里,基类的结构是确定的,编译器能直接定位到protected成员,所以不会有这个问题。
两种解决方案
你只需要给val加上明确的限定,让编译器知道它来自基类即可,有两种常用方式:
1. 使用this->前缀
this是依赖于模板参数的表达式,编译器会知道要去当前对象的基类部分查找成员:
template <class T> class SqrNum : public Num<T> { public: SqrNum(T x) : Num<T>(x) { } T getval() { return this->val * this->val; } // 用this->限定 };
2. 使用基类名称限定
直接明确指定成员来自基类Num<T>:
template <class T> class SqrNum : public Num<T> { public: SqrNum(T x) : Num<T>(x) { } T getval() { return Num<T>::val * Num<T>::val; } // 用基类名称限定 };
额外注意点
另外你的代码还缺少头文件<iostream>,因为用到了cout和endl,记得加上:
#include <iostream> using namespace std; // 或者直接使用std::cout、std::endl
修正后的代码编译运行后,会输出:
Cast from SqrNum<int>* to Num<int>* OK. Value is 9
内容的提问来源于stack exchange,提问作者Prashant Gaur
相关产品推荐
相关产品推荐

