【问题标题】:Difference between declaring static object and pointer to static object [closed]声明静态对象和指向静态对象的指针之间的区别[关闭]
【发布时间】:2016-11-27 08:50:28
【问题描述】:
    #include <iostream>
    using namespace std;
    class First{
        public:
        void fun()
        {
            cout<<"base fun called\n";
        }
    };

    class Second{
        public:
        static First x; //Line 1
        static First *y; //Line 2
    };

    First Second::x; //Line 3

    First* Second::y; //Line 4

    int main()
    {
        Second::x.fun();
        Second::y->fun();
        return 0;
    }

第 1 行和第 2 行是声明,第 3 行和第 4 行是定义,这是我从其他一些关于静态成员的 stackoverflow 帖子中了解到的。

第一季度。为什么我们必须像这样定义静态对象? (第 3 行和第 4 行)

第二季度。 x 和 y 有什么区别?(第 1 行和第 2 行)

第三季度。为 x 和 y 对象分配的内存在哪里?(第 3 行和第 4 行)

【问题讨论】:

  • 你真的应该一次问一个问题。
  • 你真的在问对象和指向对象的指针有什么区别吗?静态根本不会改变这一点。并且没有指向静态对象的指针。有一个指向对象的静态指针。

标签: c++ static-members


【解决方案1】:

您的ypointer(不是对象- 指针与其可以指向的对象不同)。因为它是static,所以它会使用nullptr 进行初始化,除非您明确 将它定义为其他东西(例如,有一些First z; 对象并定义First* Second::y= &amp;z;)。 所以Second::y-&gt;fun(); 正在取消引用一个空指针,即undefined behavior。你真的应该是very scared

我们无法在这里回答您的所有问题(需要整本书,指针及其semantics 的概念很难解释,并且与pointer aliasing 相关;另请阅读virtual address space)。所以花几个星期读一些好书,比如Programming - Principles and Practice Using C++;阅读 SICPIntroduction to Algorithms 可能也会使您受益(即使两者都不是关于 C++ 的;但是两者都与编程有关,即 difficult to learn)。

还可以查看一些好的C++ reference 站点,它对static class members 进行了简短的解释。

请注意,在真正的 C++11 中,使用原始指针通常(但不总是)是一种不好的气味。您可能应该考虑拥有smart pointers,但 YMMV。

【讨论】:

  • 从技术上讲,指针本身也是一个对象。
  • C++ 智能指针是一个对象,但不是 C++ 原始指针。您不能将任何成员函数fun 应用于y 作为y.fun();
  • 1.8 C++ 对象模型:对象是一个存储区域 - 指针也需要存储。调用成员函数的能力并不是定义对象的能力。该标准清楚地将指针,例如int 变量定义为对象(就像在C 中一样)。
  • @SChepurin 该标准定义了指针(在 8.3.1“指针”中)。所有占用存储空间的原始指针都是对象。在这个问题的上下文中,y 指定的指针显然是一个对象。从我的阅读来看,指针可能不是对象不是标准所允许的(“指针”是对象,“指针值”是它的值)。 “this 不是对象”声明实际上根本没有在标准中说明。 (this 是纯右值并不要求它不引用存储在对象中的值。)如果实际标准的部分内容相矛盾,请随意引用。
  • @Cubbi 这已经失控了。没有理由不能将 this 的值存储在 1.8 允许的临时对象中(“对象是由实现 (12.2) 在需要时创建的......)。但这不是重点;答案说“你的 y 是一个指针(不是一个对象......)”但 y 根据相同的 1.8 节定义了一个对象(它保存一个指针值)。指针变量表示对象。this 是否是对象与否与答案或问题无关,因此不在这里讨论。
【解决方案2】:

1) 因为当创建一个类的对象时,不会为它们的静态成员分配内存 - 所以第 1 行和第 2 行 声明 应该有这样的成员,但第 3&4 行 定义应该在哪里分配内存。

2) 实际上没有什么大的区别 - xy 都只是类 Second 的成员,但类型不同。 xFirst 类型,其大小等于 First 成员的总和。 y 的类型为 First* - 它的大小取决于特定编译器中使用的指针大小。

3) 已经有一个关于静态成员内存分配的good answer。最常见的实现是使用data segment的程序。

【讨论】:

    【解决方案3】:

    第一季度 当您编写class 语句时,它通常是声明。没有实际的数据成员被分配到任何地方。对于非静态成员,定义发生在实例化时,即调用构造函数时。 但是,静态成员与实例化无关。它们应该被分配一次,你应该决定在哪里。这就是实际定义的原因。该文件(编译时)将负责实际分配这些成员。

    这实际上也回答了Q3。至于Q2,我不确定确切的问题是什么。

    【讨论】:

      猜你喜欢
      • 2019-01-10
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多