静态类 - static

静态构造函数与静态类详解

 静态构造函数:
 1.一定是静态类才有静态构造函数吗? 错的
 
静态构造函数的特点:
  1.静态函数没有访问修饰符(默认修饰符为private,但是你不能写出来)
  2.静态函数是系统默认调用,程序员无法手动调用
  3.如果类没有静态构造函数,而此时类中又包含静态字段(未初始化的),那么此时编译器会默认生成静态构造函数
  4.在静态类中或者静态方法中不能使用对象
  5.如果类中包含静态成员,且没有被初始化,系统会默认提供一个默认的值,这也间接的说明了
  我们不可以直接调用静态构造函数,也没有办法控制静态函数的执行时间
  6.静态构造函数只能被调用一次,并且不能有重载
  7.静态构造函数不能有形式参数
  8.虽然静态构造函数和普通构造函数名字一样,但是系统规定他两可以共存,尽管参数列表一样
  9.静态构造函数是在普通构造函数调用之前执行,一般情况下用于初始化静态字段,
  或者拦截在实例化之前处理某些特定情况,可以再该函数实现


 
 用static修饰的类为静态类
 静态的特点:
 1.静态类不能被直接实例化
 2.静态不能被继承
 3.静态类中不能包含实例成员
 4.静态类就是特殊的密封类
 5.静态类中虽然不能包含实例成员,但是可以有常量(const常量)
 6.静态类和实例调用方式不一样,普通类是以 "实例." 的方法进行调用
 而静态类是以 "类名." 的方式进行调用
 7.静态类的访问速度相对而言比实例类要快得多
 8.如果类中包含静态构造函数和函数的入口Main函数,此时静态函数会在main函数之前调用

 9.如果类中包含静态构造函数并不包含main函数,此时会先执行main函数再执行静态构造函数


using System;

namespace 静态类 {

	class Person {
		public string name;	// 普通字段
		public static string sex = "男";	// 静态字段

		// 构造函数
		public Person () {
			Console.WriteLine ("普通构造函数被调用!~");
		}

		// 静态构造函数
		static Person () {
			Console.WriteLine ("静态构造函数被调用!~");
		}

	}
	
	class MainClass {

		// 练习1:定义一个静态类,计算一个数组的求和
		// 练习2:在上面的条件下,将数组的求和输出到一个变量中(静态成员变量),打印该静态成员变量的值
		public static void Main (string[] args) {
			new Person ();
		}
	}
		
}



/*
 * 
using System;

namespace 静态类 {
	
	// 静态 static 
	// 静态的字段、属性或者方法,只能由类调用,不能够由实例调用
	// 使用类创建的对象的过程叫做实例化,对象也可以称作实例

	// 静态类
	// 在静态类中,只能包含静态的成员(字段、属性、方法)、const常量
	public static class A {
		public static int i;

		// 静态类不能有实例的构造函数
//		public A (){
//			
//		}
		// 1.静态构造方法前不允许添加访问修饰符
		// 2.静态构造方法存在于静态类中;也可以存在于普通类中
		// 3.静态构造会在第一次实例化或调用静态成员时调用
		// 静态构造方法
		// 静态构造方法会在首次访问类中的静态成员时调用
		static A (){
			Console.WriteLine ("A的静态构造方法!~");
		}
		// 静态方法
		public static void Test(){
			Console.WriteLine ("Test");
		}
	}

	public class B {
		public static int age;
		// 静态构造会在创建对象并初始化之前调用
		static B(){
			Console.WriteLine ("B的静态构造方法!~");
		}
	}
	class MainClass {
		
		public static void Main (string[] args) {
			// 这样调用就不行了,i 这时是一个
//			A a = new A ();
//			a.i = 10;
//			Console.WriteLine (a.i);

			// 直接使用类名调用静态成员
//			A.i = 10;
//			Console.WriteLine (A.i);
//			A.Test ();

//			B b = new B();
			B.age = 10;

			// 在内存中一共有5个区域
			// 1.堆区 - 需要程序员手动开辟并管理内存
			// 2.栈区 - 由系统自动完成内存管理
			// 3.静态区(全局区) - 程序运行过程中内存中的数据一直存在
			// 4.常量区 - 用于存放常量
			// 5.代码区 - 存放程序运行所需要的代码
		}
	}
}

*/



<think>我们首先需要理解用户的问题:用户想要理解`-static-libstdc++`参数的作用,并探讨为什么没有对应的`-static-libstdc`参数用于静态链接C库。 根据引用[1]和引用[2]: - `-static-libstdc++`的作用是只将C++标准库(libstdc++.so)静态链接到可执行文件中。 - `-static`选项会将所有用到的外部库全部以静态方式链接。 - 而C标准库(libc)并没有一个单独的选项如`-static-libstdc`(注意:C标准库通常称为libc,其动态库在Linux下是libc.so,在Windows下是msvcrt.dll或类似,但GCC在Windows下使用MinGW时可能是libmsvcrt.a或类似的静态库,但这里我们讨论的是GCC的选项)。 为什么没有`-static-libstdc`选项? 1. **历史原因和命名约定**: - C++标准库在GCC中被称为`libstdc++`,因此选项命名为`-static-libstdc++`。 - C标准库在GCC中通常被称为`libc`,所以如果按照同样的命名规则,应该是`-static-libc`。但是,GCC并没有提供这个选项。 2. **C标准库的特殊性**: - 在类Unix系统中,C标准库(libc)是系统的基础库,与操作系统的内核接口紧密相关。动态链接C库(如glibc)是系统运行的基础,通常系统上的所有程序都依赖同一个动态C库。静态链接C库在某些情况下可能会引起问题,比如: - 静态链接的C库可能无法使用动态链接库的某些特性(如NSS Name Service Switch,它允许通过动态加载模块来扩展名称解析功能)。 - 如果程序静态链接了C库,那么它就不会使用系统提供的动态C库,这可能导致程序无法从系统的C库更新中受益(比如安全更新)。 - 因此,GCC开发者可能认为没有必要提供单独的`-static-libc`选项,因为静态链接整个C库通常是不推荐的。 3. **静态链接整个程序**: - 如果需要静态链接C库,可以使用`-static`选项,它会将所有库(包括libc)都静态链接。但是,这可能会带来一些兼容性和可移植性问题,尤其是在不同Linux发行版之间。 4. **技术实现**: - GCC的链接器(ld)在链接过程中,默认会链接动态库(如果有的话),除非指定了静态库。对于C标准库,通常系统会提供动态库和静态库(如`libc.a`)。我们可以通过指定库的完整路径来强制静态链接C库,例如: ```bash gcc -o myprog myprog.c /usr/lib/libc.a ``` 但是,这种方法需要知道静态库的具体位置,并且可能会因为系统不同而路径不同。 5. **为什么有`-static-libgcc`和`-static-libstdc++`?** - `libgcc`和`libstdc++`是GCC的运行时库,它们与编译器版本紧密相关。不同版本的GCC可能提供不同版本的这些库。为了避免目标系统没有安装对应版本的库,GCC提供了这两个选项来允许静态链接这些特定的库,而不需要静态链接整个程序(包括C库)。这样可以在保证可移植性的同时,减少因为库版本不一致导致的问题。 总结: - `-static-libstdc++`的作用是静态链接C++标准库(libstdc++.so),这样可执行文件就不需要在运行时依赖系统的C++标准库动态链接库。 - 没有`-static-libstdc`(或`-static-libc`)选项的原因可能是: - C标准库的特殊性(作为系统基础库,静态链接可能带来问题)。 - 静态链接整个C库通常是不被推荐的(除了特定场景,如嵌入式系统),因此GCC没有提供单独的选项。 - 如果需要静态链接C库,可以使用`-static`选项(但会静态链接所有库)或者直接指定静态库的路径。 另外,引用[3]中提到在CentOS8上安装`glibc-static`和`libstdc++-static`包,这些包提供了C和C++标准库的静态版本。安装后,我们可以使用`-static`选项来静态链接整个程序,包括C标准库。 相关问题: 1. 静态链接C标准库(libc)会带来哪些潜在问题? 2. 在Linux系统中,如何手动指定静态链接某个特定的库(如libc)? 3. 为什么在分发程序时,通常建议动态链接C标准库(glibc)?</think>### 理解`-static-libstdc++`的作用及为何没有`-static-libstdc`选项 #### 1. `-static-libstdc++`的作用详解 `-static-libstdc++`是GCC编译器特有的链接选项,其核心功能是**强制静态链接C++标准库(libstdc++.so)**。具体表现为: - **消除动态依赖**:默认情况下,GCC会动态链接C++标准库(生成依赖`libstdc++.so`或`libstdc++-6.dll`的文件)。使用此选项后,标准库代码会被直接嵌入可执行文件,移除对系统动态库的依赖[^1][^2]。 - **提升可移植性**:生成的程序可在未安装匹配版本C++运行时的系统上运行,避免`libstdc++.so not found`类错误[^2]。 - **选择性静态链接**:仅影响C++标准库,其他库(如glibc)仍保持动态链接,比`-static`(全静态链接)更轻量[^1]。 **典型使用场景**: ```bash g++ -static-libstdc++ -o myapp main.cpp # 仅静态链接C++标准库 ``` #### 2. 为何没有`-static-libstdc`选项? C标准库(glibc)没有对应的`-static-libstdc`选项,原因如下: 1. **技术限制** C标准库(glibc)与操作系统内核紧密耦合,其动态库(`libc.so`)包含**系统级接口**(如系统调用封装、线程本地存储等)。静态链接glibc会导致: - 无法使用动态加载器(ld-linux)的功能 - 破坏`pthread`线程模型的兼容性 - 禁用NSS(Name Service Switch)等动态扩展机制[^3] 2. **设计哲学差异** - C++标准库(libstdc++)是**纯用户态库**,静态链接不会影响系统接口 - glibc被视为**系统基础设施**,Linux规范要求通过动态链接共享内核接口 3. **替代方案存在** 全静态链接可通过`-static`实现: ```bash gcc -static -o myapp main.c # 全静态链接(包含glibc) ``` 但需先安装静态库(如CentOS的`glibc-static`包)[^3]。 4. **兼容性风险** 静态链接glibc会固定内核接口版本,导致: - 无法适配新内核的系统调用 - 安全更新无法通过动态库热加载 - 二进制文件可能在新系统上崩溃 #### 3. 关键差异总结 | 特性 | `-static-libstdc++` (C++库) | 理论`-static-libstdc` (C库) | |---------------------|----------------------------|----------------------------| | **可行性** | ✅ 安全可行 | ❌ 系统限制 | | **依赖关系** | 纯用户态 | 内核耦合 | | **线程支持** | 无影响 | 破坏`pthread`模型 | | **动态加载器** | 无关联 | 必需组件 | | **典型文件大小增量**| 增加1-5MB | 增加2-10MB | #### 4. 实际解决方案 若需完全静态的C程序: 1. 安装静态库包: ```bash # CentOS示例 wget http://mirror.centos.org/.../glibc-static-2.28.rpm rpm -ivh glibc-static-2.28.rpm --nodeps # 忽略依赖警告[^3] ``` 2. 全静态编译: ```bash gcc -static -o static_app main.c ``` > ⚠️ 注意:此类程序可能无法在较新内核的系统上运行 --- ### 相关问题 1. 在Linux系统中,静态链接glibc会导致哪些具体的兼容性问题? 2. 如何检查一个可执行文件的动态库依赖关系? 3. 为什么C++标准库可以安全静态链接而C标准库不行? 4. 在Windows平台使用MinGW时,静态链接C库有哪些注意事项? [^1]: -static 会将所以有用到的外部库全部以静态的方式链接 -static-libstdc++ 只将libstdc++.so静态链接 [^2]: 链接选项:-static -static-libgcc -static-libstdc++... 这种方式生成的可执行文件会比动态链接的版本大 [^3]: centos8安装glibc-static和libstdc++-static静态链接... 需要下载安装包并处理依赖
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值