C++实现对象内自指指针 嵌套类访问外部成员报错解决
错误原因
- 核心问题是C++的嵌套类不会自动持有外层类的实例上下文:
Handle作为Myclass的嵌套类是独立类型,没有隐式的外层Myclass对象的this指针,直接将外层类非静态成员mClass写在Handle的构造函数初始化列表里,编译器无法定位mClass所属的具体实例,就会抛出你看到的非静态成员非法使用的编译错误。 - 其次代码存在逻辑和类型不匹配问题:你声明
ptr为Handle*类型,但写的&mClass[i]是Handle**类型(mClass本身是二级指针,下标访问得到一级指针,取地址后为二级指针),类型完全不匹配;且需求是让ptr指向Handle实例自身,直接用实例自带的this指针即可,完全不需要绕路访问外层类的mClass成员。 - 原代码还存在基础语法疏漏:嵌套类
Handle定义结尾缺少分号,Myclass构造函数没有正确闭合,也没有编写对应的析构逻辑释放动态申请的内存,会引发内存泄漏。
修复方法
如果只需要实现Handle内部的ptr指向实例自身,直接在Handle构造函数初始化列表里给ptr赋值this即可,不需要在Handle的逻辑里触碰外层类的mClass成员。所有涉及mClass数组的增删改操作,放到Myclass的成员函数中实现——Myclass的成员函数持有当前实例的this指针,可以合法访问mClass成员。
如果后续确实需要在Handle实例内部访问外层Myclass的成员,可以给Handle增加一个外层类指针成员,构造Handle实例时显式传入外层类的this指针即可。
修复后的可编译参考代码如下:
template<typename T> class Myclass { private: const unsigned mCapacity; unsigned mSize; class Handle; Handle **mClass; class Handle { friend Myclass; private: unsigned index; T mVal; Handle *ptr; // 若需要访问外层实例,取消注释下一行 // Myclass* outer; public: Handle(unsigned i, T t/*, Myclass* o 如果需要外层指针加这个参数*/) : index(i), mVal(t), ptr(this) // 直接用this指向当前实例自身 // ,outer(o) 持有外层实例指针 {} }; public: Myclass(unsigned capacity) : mCapacity(capacity), mSize(0), mClass(new Handle*[capacity]) { // Myclass成员函数可合法访问mClass,这里做数组初始化 for (unsigned i = 0; i < mCapacity; i++) { mClass[i] = nullptr; } } // 必须编写析构函数释放动态内存,避免泄漏 ~Myclass() { for (unsigned i = 0; i < mSize; i++) { delete mClass[i]; } delete[] mClass; } // 注意:类中包含动态申请的资源,需要按需实现拷贝构造、拷贝赋值运算符,禁止浅拷贝 };
如果要在Handle中访问外层mClass,构造Handle时传入外层this即可,示例:
// Myclass成员函数中创建Handle实例的写法 mClass[mSize] = new Handle(mSize, t, this);
内容的提问来源于stack exchange,提问作者pointerToMe
相关产品推荐
相关产品推荐

