声明静态对象和指向静态对象的指针之间的区别
Difference between declaring static object and pointer to static object
#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 行是定义,这是我从其他一些关于静态成员的 Whosebug 帖子中了解到的。
Q1。为什么我们必须这样定义静态对象? (第 3 行和第 4 行)
Q2。 x 和 y 有什么区别?(第 1 行和第 2 行)
Q3。为 x 和 y 对象分配的内存在哪里?(第 3 行和第 4 行)
您的 y
是一个 pointer(不是对象 - 指针与它可能指向的对象不同)。因为它是 static
,所以它用 nullptr
初始化,除非你 明确地 定义它初始化为其他东西(例如有一些 First z;
对象并定义First* Second::y= &z;
)。
所以 Second::y->fun();
正在取消引用空指针,即 undefined behavior. You really should be very scared.
我们无法在这里回答您的所有问题(需要整本书,指针的概念及其 semantics is difficult to explain, and related to pointer aliasing; read also about virtual address space). So take a few weeks to read some good book like Programming - Principles and Practice Using C++; you probably will benefit by also reading SICP & Introduction to Algorithms (even if neither is about C++; however both are related to programming, which is difficult to learn)。
又见一些不错的C++ reference site, it gives a short explanation about static
class members.
请注意,在真正的 C++11 中,使用原始指针通常(但不总是)是一种难闻的气味。你可能应该考虑 smart pointers,但是 YMMV.
Q1
当您编写 class
语句时,它通常是声明。任何地方都没有分配实际的数据成员。对于非静态成员,定义发生在实例化时,即调用构造函数时。
但是,静态成员与实例化无关。它们应该被分配一次,你应该决定在哪里。这就是实际定义的原因。该文件(编译时)将负责实际分配这些成员。
这实际上也回答了 Q3。至于Q2,我不确定具体问题是什么
1) 因为当创建 class 的对象时,不会为它们的静态成员分配内存 - 所以第 1 行和第 2 行 声明 应该有这样的成员,但是第 3 和 4 行 定义了 应该分配内存的位置。
2) 字面上没有太大区别 - x
和 y
都只是 class Second
的成员,但类型不同。 x
属于 First
类型,其大小等于 First
个成员的总和。 y
属于 First*
类型 - 它的大小取决于特定编译器中使用的指针的大小。
3) 已经有一个good answer about memory allocation for static members. The most common implementation is to use data segment的程序。
#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 行是定义,这是我从其他一些关于静态成员的 Whosebug 帖子中了解到的。
Q1。为什么我们必须这样定义静态对象? (第 3 行和第 4 行)
Q2。 x 和 y 有什么区别?(第 1 行和第 2 行)
Q3。为 x 和 y 对象分配的内存在哪里?(第 3 行和第 4 行)
您的 y
是一个 pointer(不是对象 - 指针与它可能指向的对象不同)。因为它是 static
,所以它用 nullptr
初始化,除非你 明确地 定义它初始化为其他东西(例如有一些 First z;
对象并定义First* Second::y= &z;
)。
所以 Second::y->fun();
正在取消引用空指针,即 undefined behavior. You really should be very scared.
我们无法在这里回答您的所有问题(需要整本书,指针的概念及其 semantics is difficult to explain, and related to pointer aliasing; read also about virtual address space). So take a few weeks to read some good book like Programming - Principles and Practice Using C++; you probably will benefit by also reading SICP & Introduction to Algorithms (even if neither is about C++; however both are related to programming, which is difficult to learn)。
又见一些不错的C++ reference site, it gives a short explanation about static
class members.
请注意,在真正的 C++11 中,使用原始指针通常(但不总是)是一种难闻的气味。你可能应该考虑 smart pointers,但是 YMMV.
Q1
当您编写 class
语句时,它通常是声明。任何地方都没有分配实际的数据成员。对于非静态成员,定义发生在实例化时,即调用构造函数时。
但是,静态成员与实例化无关。它们应该被分配一次,你应该决定在哪里。这就是实际定义的原因。该文件(编译时)将负责实际分配这些成员。
这实际上也回答了 Q3。至于Q2,我不确定具体问题是什么
1) 因为当创建 class 的对象时,不会为它们的静态成员分配内存 - 所以第 1 行和第 2 行 声明 应该有这样的成员,但是第 3 和 4 行 定义了 应该分配内存的位置。
2) 字面上没有太大区别 - x
和 y
都只是 class Second
的成员,但类型不同。 x
属于 First
类型,其大小等于 First
个成员的总和。 y
属于 First*
类型 - 它的大小取决于特定编译器中使用的指针的大小。
3) 已经有一个good answer about memory allocation for static members. The most common implementation is to use data segment的程序。