指向Base::Inner类的匿名与命名内部派生类的指针行为差异
问题分析与解决:内部类指针访问异常
问题现象
在给定的C++代码中,Derived_GrandChild构造函数访问基类Base的两个指针时:
- 指向匿名内部派生类实例的指针能正确输出
test_int = 1 - 指向命名内部派生类的指针输出未初始化的垃圾值(
-858993460)
核心原因
两种指针的差异源于所指向对象的生命周期不同:
- 匿名内部派生类实例
anonymous_inner_derived:它是Derived类的成员变量,生命周期与Derived(或其派生类Derived_GrandChild)对象完全绑定。只要Derived对象存在,该实例就处于有效状态,因此指针访问正常。 - 命名内部类
Inner_Derived的局部实例inner_derived:它是Derived构造函数内的局部变量,构造函数执行完毕后,该局部变量会被销毁,对应的内存区域被释放或标记为可复用。此时inner_class_ptr_to_inner_derived_class成为悬空指针,后续通过它访问成员属于C++未定义行为,输出垃圾值是典型表现。
修复方案
要解决这个问题,需要让命名内部类的实例生命周期与Derived对象一致,以下是两种可行方式:
方案1:将实例改为类成员变量
直接把Inner_Derived的实例定义为Derived的成员变量,确保其生命周期与类对象绑定:
class Base { public: class Inner { public: int test_int = 1; }; Inner* inner_class_ptr_to_anonymous_inner_derived_class; Inner* inner_class_ptr_to_inner_derived_class; }; class Derived : public Base { public: class Inner_Derived : public Base::Inner {}; Inner_Derived inner_derived; // 改为Derived的成员变量 class : public Base::Inner {}anonymous_inner_derived; Derived() { inner_class_ptr_to_inner_derived_class = &inner_derived; inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived; } }; class Derived_GrandChild : public Derived { public: Derived_GrandChild() { std::cout << "Anonymous Inner Derived Class test_int = " << inner_class_ptr_to_anonymous_inner_derived_class->test_int << std::endl; std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl; } };
方案2:动态分配内存(需管理内存)
如果需要按需创建实例,可使用new在堆上分配对象,此时对象生命周期由程序员控制,需注意添加析构函数释放内存避免泄漏:
class Base { public: class Inner { public: int test_int = 1; }; Inner* inner_class_ptr_to_anonymous_inner_derived_class; Inner* inner_class_ptr_to_inner_derived_class; }; class Derived : public Base { public: class Inner_Derived : public Base::Inner {}; class : public Base::Inner {}anonymous_inner_derived; Derived() { inner_class_ptr_to_inner_derived_class = new Inner_Derived(); // 堆上分配 inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived; } // 析构函数释放堆内存 ~Derived() { delete inner_class_ptr_to_inner_derived_class; } }; class Derived_GrandChild : public Derived { public: Derived_GrandChild() { std::cout << "Anonymous Inner Derived Class test_int = " << inner_class_ptr_to_anonymous_inner_derived_class->test_int << std::endl; std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl; } };
内容的提问来源于stack exchange,提问作者Kubrickesque
相关产品推荐
相关产品推荐

