static对象

本文详细探讨了C++中静态对象的两种类型:局部静态对象和非局部静态对象,并解释了它们的生命周期特点及初始化顺序的不确定性。文章还提供了解决非局部静态对象间相互依赖问题的方法。

static对象:一旦被创建,就一直存在,直到程序退出。

根据静态对象的位置不同,可以分为两类:non-local static object与local static object

具体来说:

local static object:指函数中用static修饰符修饰的object

生命期起始时间:在函数第一次调用时构造初始化。

生命期终止时间:程序结束

non-local static object:包括全局objects,在名词空间范围的objects,类中用static修饰符修饰的objects

生命期起始时间:在main函数调用之前被构造初始化。

生命期终止时间:程序结束

注意:在同一个文件或不同编译单元(不同文件)中,如果存在多个non-local static object,它们都是在主函数调用之前被构造的,但是它们之间的构造顺序时不定的。即对编译器来说,静态成员对象之间的初始化顺序和析构顺序是一个未定义的行为。

因此,不能用某个non-local static object去初始化non-local static object,无论这两个non-local static object在不在同一个编译单元中。

下面给出一个处在两个编译单元(CPP文件)中的non-local static object相互引用的情况:

class FileSystem 
{
public: …
	std::size_t numDisks() const;
};

extern FileSystem tfs;

//另一编译单元

class Directory 
{
public:
	Directory(params);
};

Directory::Directory(params) 
{
	std::size_t disks = tfs.numDisks();//使用另一个编译单元的静态变量
}

Directory tempDir (params);
由于编译器没有定义non-local static object之间的构造顺序,所以有可能类tfs还没有被构造,所以程序可能会报错。

解决方法:用local static对象替换non-local static对象。

C++保证,函数内的local static 对象会在该函数被调用期间,首次遇上该对象定义式时被初始化。

class FileSystem {…};

FileSystem& tfs() 
{
	static FileSystem fs;
	return fs;
}

//另一编译单元
class Directory {…};

Directory::Directory (params) 
{
	std::size_t disks = tfs().numDisks();//执行函数tfs时,对象fs肯定会被构造。
};

Directory& tempDir() 
{
	static Directory td;
	return td;
}

在编程语言中,`static`对象通常指的是类的静态成员(如静态变量、静态方法等),它们属于类本身而非类的实例。因此,`static`对象的比较行为与普通对象的比较存在显著差异,具体取决于语言的设计和实现。 ### Java 中的 `static` 对象比较 在 Java 中,静态变量属于类,而不是类的实例。比较两个类的静态变量时,实际上比较的是这些变量的值。如果变量是基本类型,则直接比较其数值;如果是引用类型,则比较的是引用地址,除非重写了 `equals()` 方法来比较内容。 例如: ```java class Example { static Integer a = 10; static Integer b = 10; } if (Example.a == Example.b) { System.out.println("Equal"); } else { System.out.println("Not Equal"); } ``` 上述代码输出 `"Equal"`,因为 Java 缓存了 `Integer` 值在 -128 到 127 之间的实例,所以 `a` 和 `b` 引用的是同一个对象。但如果超出这个范围,则可能返回 `"Not Equal"`,因为它们可能引用不同的对象 [^2]。 ### C++ 中的 `static` 对象比较 在 C++ 中,静态成员变量是类级别的变量,它们的比较方式与普通变量相同。对于基本类型,直接使用 `==` 运算符进行比较;对于自定义类型,则需要重载比较运算符或调用相应的比较函数。 ```cpp class Example { public: static int a; static int b; }; if (Example::a == Example::b) { std::cout << "Equal"; } else { std::cout << "Not Equal"; } ``` ### Python 中的 `static` 对象比较 Python 中没有显式的 `static` 关键字,但可以通过类变量来模拟静态变量。类变量属于类本身,而不是类的实例。比较类变量时,同样使用 `==` 运算符进行值比较。 ```python class Example: a = 10 b = 10 if Example.a == Example.b: print("Equal") else: print("Not Equal") ``` ### 仓颉编程语言中的 `static` 对象比较 在仓颉编程语言中,静态变量的行为与 Java 或 C++ 类似,比较静态变量时直接比较其值。对于值类型,赋值时会产生拷贝,因此比较的是值;对于引用类型,比较的是引用地址,除非重写比较逻辑。 ```langue struct Copy { var data = 2012 } class Share { var data = 2012 } main() { let c1 = Copy() var c2 = c1 c2.data = 2023 println("${c1.data}, ${c2.data}") // 输出 2012, 2023 let s1 = Share() let s2 = s1 s2.data = 2023 println("${s1.data}, ${s2.data}") // 输出 2023, 2023 } ``` ### 不同语言中 `static` 对象比较的总结 | 语言 | 比较方式 | 说明 | |------|----------|------| | Java | `==` 或 `equals()` | 基本类型直接比较值,引用类型比较引用地址,除非重写 `equals()` | | C++ | `==` 或自定义运算符 | 基本类型直接比较值,自定义类型需重载比较运算符 | | Python | `==` | 类变量比较值 | | 仓颉 | `==` | 值类型比较值,引用类型比较引用地址 | 在不同语言中,`static` 对象的比较行为可能会有所不同,具体取决于语言的设计和实现。在进行跨语言开发时,需要注意这些差异以避免潜在的错误 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值