类成员内存分配
我的问题主要是理论上的。 假设我们有一堂课
class A{
private:
int * a;
int b;
private:
A(){
a = new int[100];
b = 100;
}
~A(){
delete [] a;
}
}
据我所知,如果我们动态地创建类型A的对象( A * a = new A()
),则此对象的内存将在堆中分配,如果我使用( A a
)它将在堆栈(A a)
。 在当对变量栈存储器对象被创建的情况下a
上堆和的情况下,当我们在堆内存对象分配对象分配的意愿b
将在堆栈进行分配。 对我来说第一个问题是确定的:对吗?
第二个问题是将堆的所有成员存储在堆内存或堆栈内存中效率更高吗?
class A{
private:
int * a;
int * b;
private:
A(){
a = new int[100];
b = new int(100);
}
~A(){
delete [] a;
delete b;
}
}
当我说有效率时,我的意思是关于类成员的所有数据将以堆或堆栈的形式存储在内存中(实际上,我不确定它们是否正确地存储在彼此附近)。
首先,C ++中没有堆或堆栈。 相反,我们有自动存储时间和动态存储时间。 具有自动存储持续时间的对象是一个有作用域的对象。 当它超出范围时,它会自动清理。 另一方面,具有动态存储持续时间的对象不受其范围的限制。 它的生命周期只有在程序明确结束时才会结束(通常这意味着调用delete
)。
现在在A
您有一个存储自动存储时间的对象, b
和一个存储持续时间为a
。 这意味着b
将居住在A
实例的任何地方。 a
也存在于A
实例中,但它指向的内存将驻留在内存中的某处,但我们不知道在哪里。 当实例被销毁时, b
会自动清理,但是a
会需要在析构函数中进行特殊处理,否则内存将会泄漏。 你可以想像它
A
+------+ +----------+
| a->+---| 100 ints |
| b | +----------+
+------+
就效率而言,一些程序员老兄提到你不应该为此担心。 你应该使用你所投下的类型适合这份工作。 一旦完成并运行,你就可以对其进行分析,找到瓶颈。 如果由于使用指针而看到太多缓存未命中,那么您可以查看试图将数据本地化到类本身。
我还想提一下,如果你发现自己写some_type* name = new/new[]
那么你应该考虑使用std:unique_ptr<some_type>/std:unique_ptr<some_type[]>
或std::vector<some_type>
。
不,你不完全正确。
a
和b
是你的对象内部的变量。 它们都扩展了你的类的大小 - 至少是sizeof(int*)
的大小。
根据您构建对象的方式,如上所述,此变量的内存分配在堆栈或堆上:
new A/int/etc
在堆上分配内存
A/int/etc. var
A/int/etc. var
在堆栈上分配内存
你错过的是你的数据在构造函数中分配
a = new int[100];
不是你的类对象的一部分。 这是一些外部数据。 在你的类对象中,你只有一个int*
成员(大小为4-8字节,取决于体系结构)指向这些数据。
首先,成员原始指针(例如MyClass
)的缺点是它强制#include
声明MyClass
的头部。 这可能导致编译速度缓慢。 要解决您可以使用带前向声明的智能指针。
第二个问题是将堆的所有成员存储在堆内存或堆栈内存中效率更高吗?
通常最好只在必要时使用指针。 你通常应该在课堂上将成员声明为值。 它将是本地的,错误的机会会减少,分配的次数也会减少,最终可能出错的东西也会减少,编译器总是可以知道它在指定的偏移量处存在,所以它有助于优化和减少二进制数水平。
链接地址: http://www.djcxy.com/p/14079.html