模板派生类DerivedList无法访问基类List私有成员的问题排查
问题:模板类友元无法访问私有成员的编译错误
我定义了List和DerivedList两个模板类,希望DerivedList能够访问List类的私有成员,于是将DerivedList声明为List的友元类,但编译代码时出现如下错误:
DerivedList.cpp: In member function ‘void DerivedList<T, size>::addItem(T*)’: DerivedList.cpp:5:3: error: ‘m_data’ was not declared in this scope 5 | m_data[size - m_length - 1] = item; | ^~~~~~ DerivedList.cpp:5:17: error: ‘m_length’ was not declared in this scope 5 | m_data[size - m_length - 1] = item; | ^~~~~~~~ DerivedList.cpp: In member function ‘T* DerivedList<T, size>::removeItem(T*)’: DerivedList.cpp:11:3: error: ‘m_data’ was not declared in this scope 11 | m_data[size - m_length] = nullptr; | ^~~~~~ DerivedList.cpp:11:17: error: ‘m_length’ was not declared in this scope 11 | m_data[size - m_length] = nullptr; | ^~~~~~~~
我的代码
List.h
template <class T, int size> class DerivedList; template <class T, int size> class List { friend class DerivedList<T, size>; private: T** m_data[size]; int m_length{0}; public: List(){}; virtual void addItem(T* item); virtual T* removeItem(T* item); };
List.cpp
#include "List.h" template <class T, int size> void List<T, size>::addItem(T* item) { m_data[m_length] = item; m_length++; }; template <class T, int size> T* List<T, size>::removeItem(T* item) { m_data[m_length - 1] = nullptr; m_data--; };
DerivedList.h
#include "List.h" template <class T, int size> class DerivedList : public List<T, size>{ public: DerivedList() : List<T, size>(){}; void addItem(T* item); T* removeItem(T* item); };
DerivedList.cpp
#include "DerivedList.h" template <class T, int size> void DerivedList<T, size>::addItem(T* item) { m_data[size - m_length - 1] = item; m_length++; }; template <class T, int size> T* DerivedList<T, size>::removeItem(T* item) { m_data[size - m_length] = nullptr; m_data--; };
请问我哪里出错了或遗漏了什么?
解答
你遇到的问题主要有两个核心原因,同时代码里还有几处细节错误需要修正:
1. 模板基类的依赖名称查找问题
虽然你已经将DerivedList声明为List的友元,但在模板派生类中访问基类的私有成员时,由于模板的依赖名称查找规则,编译器无法自动识别m_data和m_length属于基类List<T, size>。
你需要显式指明这些成员的所属类,或者通过this->来访问:
修改方式一:显式限定基类
在DerivedList的成员函数中,用List<T, size>::限定成员:
template <class T, int size> void DerivedList<T, size>::addItem(T* item) { List<T, size>::m_data[size - List<T, size>::m_length - 1] = item; List<T, size>::m_length++; }; template <class T, int size> T* DerivedList<T, size>::removeItem(T* item) { List<T, size>::m_data[size - List<T, size>::m_length] = nullptr; List<T, size>::m_length--; // 原代码的m_data--是错误的 };
修改方式二:使用this->访问
利用this指针来引导编译器查找基类成员:
template <class T, int size> void DerivedList<T, size>::addItem(T* item) { this->m_data[size - this->m_length - 1] = item; this->m_length++; }; template <class T, int size> T* DerivedList<T, size>::removeItem(T* item) { this->m_data[size - this->m_length] = nullptr; this->m_length--; };
2. 模板类的实现不能放在独立的.cpp文件中
C++模板是按需实例化的,编译器需要在使用模板的地方看到完整的模板定义(包括成员函数实现)。如果把模板成员函数放在.cpp文件中,编译器在实例化模板时无法找到实现代码,后续会出现链接错误。
解决方法是:将List.cpp和DerivedList.cpp中的实现代码,分别移到对应的头文件末尾,或者使用头文件包含的方式(比如在List.h末尾#include "List.cpp")。
3. 代码中的细节错误
List类的removeItem函数中,m_data--;是错误的:m_data是固定大小的数组,不能进行递减操作,正确逻辑应该是m_length--;。DerivedList的removeItem函数同样存在m_data--;的错误,需要改为m_length--;。
内容的提问来源于stack exchange,提问作者kevinuulong
相关产品推荐
相关产品推荐

