管理嵌套类的内存

问题描述 投票:0回答:1

假设我有一些名为

A
B
C
的嵌套类。
C
类型的对象包含
B
类型的成员。
B
类型的对象包含
A
类型的成员。

C
类型的对象在堆上实例化。这个类对象和它的子对象是一个,所以所有东西最终都在堆上。

C
B
的实现中,显式持有指针有什么好处吗?类似下面的代码吗?

一方面,遵循指针链来访问数据似乎效率低下。另一方面,如果不能保证外部类在堆上声明,也许内部类保存指针“更安全”?还有什么吗?

#include <iostream>
#include <memory> // std::unique_ptr

class A;
class B;
class C;

class A {
public:
    A() {
        std::cout << "Constructor of A" << std::endl;
    }
    ~A() {
        std::cout << "Destructor of A" << std::endl;
    }
};

class B {
public:
    std::unique_ptr<A> a_member; 

    B() : a_member(std::make_unique<A>()) { 
        std::cout << "Constructor of B" << std::endl;
    }
    ~B() {
        std::cout << "Destructor of B" << std::endl;
    }
};

class C {
public:
    std::unique_ptr<B> b_member; 

    C() : b_member(std::make_unique<B>()) { 
        std::cout << "Constructor of C" << std::endl;
    }
    ~C() {
        std::cout << "Destructor of C" << std::endl;
    }
};

int main() {
    auto c_ptr = std::make_unique<C>(); 
    return 0;
}
c++ oop memory-management
1个回答
0
投票

显式持有指针有什么好处吗?

默认情况下,您应该将成员变量作为父级的一部分,而不是由唯一指针保存。如果代码中没有任何可疑的内容(例如无限递归函数,或者自己实现列表类),那么遇到堆栈溢出的情况是非常罕见的。但在多种情况下指针会很有用。

  1. Pimpl 习惯用法,即您没有公开子对象的详细信息,或者您正在使用类型擦除,而子对象的详细信息甚至不知道。
  2. 多态性,您持有指向某个基类的指针,并传递指向派生类型的指针(依赖注入)

由于提到的代码没有使用这些功能中的任何一个,因此直接将子元素保留为成员(而不是使用 unique_ptr)在存储和性能方面会更好。

© www.soinside.com 2019 - 2024. All rights reserved.