是在堆或堆栈上创建的不称为指针的类本地变量

Are variables local to a class that are not declared as pointers, created on the heap or stack?

本文关键字:指针 变量 堆栈 创建      更新时间:2023-10-16

采取以下内容:

A a;
class B; // No content for brevity
class A
{
public:
    A()
    {
         b.SetTitle("hi");
    }
private:
    B b;
}
int main()
{
    return 0;
}

这里的问题是在堆或堆栈上声明了b是否在A中声明。

如果在堆上,这是否意味着它被自动删除,或者我也必须删除它?

附带问题:

这是我最初在做的事情P>

A a;
class B; // No content for brevity
class A
{
public:
    A()
    {
         this->b( new B() ); // I don't have C++ 14 :( so i can't do make_unique
         b->SetTitle("hi");
    }
private:
    unique_ptr<B> b;
}
int main()
{
    return 0;
}

在固定内存块中仍然可以是甚至(如托马斯·马修斯(Thomas Matthews)指出的那样)。在这种情况下,您可以将其视为"内部"。如果您将堆放在堆上,则在堆上。如果您在功能的顶部分配" a",例如,它在堆栈上(但在A内)。

这样写的是A的一部分,其寿命与A有关。您只需要担心管理A。

代码示例:堆栈与堆。

// Not a proper class but used for demonstration purposes
class SomeClass {
private:
    int x;
    int* ptr;
public:        
    SomeClass() {
        // Both On x and ptr are on the stack when this constructor is defined and used.
        x = 10; 
        ptr = &x;
    } 
    SomeClass() { 
        // x is on the stack but ptr is on the heap and delete needs to be called to release the memory.
        x = 10;
        ptr = new int;
    }          
};
void someOtherFunction() {
    SomeClass a;  // on the stack relative to this function
    SomeClass* ptr = nullptr; // ptr is on the stack and is initialize to null.
    ptr = &a; // Still on the stack and ptr stores the address of (a).  
    ptr = new SomeClass(); // Now ptr lives on the heap and delete needs to be called to release its memory.         
}

最初(PTR)没有存储在其中的地址,因为我们在声明它后将其初始化为nullptr。它存储在堆栈中,此时(PTR)的地址具有一个地址,该地址是堆栈内存地址的一部分。现在,我们将(a)的地址分配给(ptr);(ptr)仍在堆栈上,(a)在堆栈上,(a)的地址存储在(ptr)中。

我们设置(ptr)= new someclass(),在这一点上,编译器将记忆抛开,并以此类对象的大小固定内存,并将随机地址从堆中保存到(ptr)中。(PTR)本身仍在此功能的堆栈中,但是(PTR)现在存储的内存地址来自堆。(PTR)的内容在此功能范围之外可访问,但需要通过此函数返回返回类型或通过参考来返回其参数之一。

另一个单词(ptr)的地址在此功能中不变,由于变量(PTR)本身仍然存在于堆栈中,因此它保持不变使用新的内存地址。

在main()中演示此代码并查看结果;这仍然适用于其他功能和类结构对象。

#include <iostream> 
int main() {
    int a = 10;
    int* ptr = nullptr;
    std::cout << "Memory Address that ptr is pointing to: " << ptr << std::endl;
    std::cout << "Memory Address of ptr: " << &ptr << std::endl;
    // std::cout << "What is stored in the variable at this memory address: " << *ptr << std::endl; // This can not be called program will crash,
    // ptr can not be dereferenced for it is not pointing to anything
    std::cout << std::endl;
    ptr = &a;
    std::cout << "Memory Address that ptr is pointing to: " << ptr << std::endl;
    std::cout << "Memory Address of ptr: " << &ptr << std::endl;
    std::cout << "What is stored in the variable at this memory address: " << *ptr << std::endl;
    std::cout << std::endl;
    ptr = new int;
    *ptr = 12;
    std::cout << "Memory Address that ptr is pointing to: " << ptr << std::endl;
    std::cout << "Memory Address of ptr: " << &ptr << std::endl;
    std::cout << "What is stored in the variable at this memory address: " << *ptr << std::endl;
    std::cout << std::endl;
    delete ptr;
    return 0;
}

您可以看到(ptr)的内存地址不会更改,因此会更改的是存储在(PTR)中的内存地址。现在,如果您在另一个指向(ptr)的指针上使用新的地址,则可以更改(PTR)。

现在,当您在类类型上调用新的新调用,然后将堆内存地址存储到该类型的指针中时,内存地址是类对象所处的位置,因此在这种情况下,任何属于此类的东西都在堆上。


Globals&amp;静态变量:

  • Globals-在(程序文件名称空间)*中列出了全球范围,并且可以访问文件中的任何地方并具有申请的寿命。

  • 静态局部变量就像全局变量一样,除了它们仅在声明的函数中访问,并且每个应用程序运行时只能初始化一次。他们有申请的寿命。

  • 静态成员变量的类别与常规静态变量相似,但它们没有与之关联的(此)指针。它们对声明它们的函数可见,每个应用程序运行时初始初始化一次,并且它们的寿命是运行时间或直到不再存在该类对象的实例。

(*)不知道技术名称,但是使用程序文件名称空间根据全局变量及其内存的表现是有意义的。 - 我很少使用全局变量!


这是引用的一些链接。

  • 堆栈与堆:stackoverflow
  • 变量&amp;内存
  • static&amp;全局内存
  • static&amp;全局变量