静态对象的非静态成员在哪里分配?

时间:2015-04-16 08:27:55

标签: c++ object

我有这个代码,我想知道内存分配。

 void f(){
        static A a;
        //Other things...
    }

    class A {
        public:
           A();
        private:
            AnotherObjectType anotherObject;
    };

anotherObject将在哪里分配?在static代码段或其他地方?是否存在覆盖anotherObject的风险? (f将被多次调用)。

5 个答案:

答案 0 :(得分:5)

所有非堆对象都将位于静态段中,位于f()的静态A实例中。

关于覆盖,如果你在多线程代码中使用了各种单例惯用语,这可能发生在旧的C / C ++中。但是例如较新的gcc版本使用新标准要求进行静态对象的自动线程安全初始化。参见例如Is local static variable initialization thread-safe in C++11?

答案 1 :(得分:1)

内存分配静态动态。动态分配是在运行时分配内存时获得的,例如newmalloc。静态分配是“其余的”。类成员变量的内存与类实例一起分配,因此如果静态分配,则成员最终位于内存的同一部分,如果动态分配,则成员最终会占用动态内存所在的位置。对于指针成员变量也是如此,但它指向的实际内存可以是动态(newmalloc)或静态分配。

int i = 0;
int* pi = &i;     // pi points at statically allocated memory
pi = new int(0);  // pi points at dynamically allocated memory

因此,如果你有一个静态类实例,那么它及其成员的内存通常是在代码段中分配,但这是一个实现细节。

如果成员是一个指向动态分配内存的指针,那么该内存将所使用的分配器决定。 “堆”是动态分配内存的最常见实现细节,使用newmalloc通常获取,但可以使用自定义分配器,即使在代码段中也能控制其他地方的内存。

答案 2 :(得分:0)

变量a是一个静态变量,只声明一次,这意味着A a;语句只执行一次。变量的范围高于函数f范围。字段anotherObject在分配范围内 A对象。

参见计数示例:

#include <iostream>
using namespace std;
class AnotherObjectType {};

class A {
public:
   A(){count = 0;};
    int count;
private:
    AnotherObjectType anotherObject;
};

 A f(){
    static A a;
    a.count++;
    //Other things...
    return a;
}

int main() {
    // your code goes here
    A a;
    for (int i = 0; i < 3; i++) {
        a = f();
        std::cout << "Count: " << a.count  << std::endl;
    }
    return 0;
}

工作示例:http://ideone.com/USqeEZ

另请参阅:http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

答案 3 :(得分:0)

void f(){
    /// this created in static segment - that's obviously for you
    static A a;
    //Other things...
}

class A {
    public:
       A();
    private:
        /// anotherObject is not pointer but explicit part of A,
        /// so it won't be created in heap or anywhere else,
        /// but in the same memory segment as an instance of A.
        AnotherObjectType anotherObject;
};

因此,另一个对象不会被覆盖,因为static A a在静态段中创建一个A实例,而其他任何实例将在其他段中被创建,具体取决于您将创建它的段。

答案 4 :(得分:0)

尽管两者都称为 static ,但静态成员与静态局部变量不同。

在类中共享静态成员。该类的每个实例都指向同一个成员。

静态局部变量初始化一次,并且在函数返回时不会被销毁。

在您的代码中,非静态成员存储在实例a中,a在函数返回之后仍然存在。