深入篇【C++】类与对象:构造函数+析构函数

news2024/11/26 20:30:55

深入篇【C++】类与对象:构造函数+析构函数

  • ①.构造函数
    • Ⅰ.概念
    • Ⅱ.特性
      • 1.函数名和类型相同。
      • 2.无返回值,也不用写void。
      • 3.自动调用对应的构造函数。
      • 4.构造函数可重载
      • 5.编译器的无参构造
      • 6.编译器的无参构造特性
      • 7.声明时可缺省
      • 8.构造函数的调用
      • 9.默认构造函数
  • ②.析构函数
    • Ⅰ.概念
    • Ⅱ.特性
      • 1.类名前+符号~。
      • 2.无参数也无返回值。
      • 3.析构无重载
      • 4.自动调用对应的析构函数
      • 5.编译器的析构特性

在这里插入图片描述

①.构造函数

如果一个类中什么成员都没有,简称为空类。
而空类并不是什么都没有,当类中什么都不写时,编译器会自动生成以下6个默认成员函数。

默认成员函数:用户没有显示的写出来,编译器会自动生成的成员函数称为默认成员函数。
主要有构造函数,析构函数,拷贝函数等。

在这里插入图片描述
本篇主要总结构造函数和析构函数

Ⅰ.概念

构造函数是一个特殊的成员函数,名字和类名相同,创建类类型行对象时由编译器自动调用,来保证每个数据成员都有一个合适的初始值,并且在对象整个生命周期只调用一次。

比如下面这个栈:

typedef int DataType;
struct stack//class可以定义一个类
{
public://访问限定符

	void Init()
	{
		_array = (DataType*)malloc(sizeof(DataType) * 3);
		if (_array == NULL)
		{
			perror("malloc");
		}
		_capacity = 3;
		_size = 0;
	}
	void Push(DataType data)
	{
		CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	void Pop()
	{
		if (Empty())
		{
			return;
		}
		--_size;

	}
	DataType Top()
	{
		return _array[_size - 1];
	}
	int Empty()
	{
		return _size == 0;
	}
	int Size()
	{
		return _size;
	}
	void Destroy()
	{
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}

private://访问限定符
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity * 2;
			DataType* temp =(DataType*)realloc(_array, sizeof(DataType) * newcapacity);
			if (temp == NULL)
			{
				perror("realloc");
		    }
			_array = temp;
			_capacity = newcapacity;
		}
	}
private://访问限定符
	DataType* _array;
	int _capacity;
	int _size;
};

int main()
{
	stack s;//定义一个对象
	s.Init();
	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Push(4);
	s.Push(5);
	printf("%d\n", s.Top());
	printf("%d\n", s.Size());
	s.Pop();
	s.Pop();
	printf("%d", s.Top());
	s.Destroy();
	return 0;
}

对于这个栈,我们如果想要使用它的话,必须要先初始化它,才可以使用,不然会报错。
比如不初始化它结果:程序是卡死的。在这里插入图片描述
但如果每次创建对象时都要调用初始化函数,来初始信息,未免有点复杂,那能否在对象创建的时候就将信息设置进去呢?
【现在遇到的问题】:

1.可能经常会忘记写初始化和销毁。
2.而且有些地方写起来很繁琐,令人脑大很大。

C++给出的解决方法:构造函数

Ⅱ.特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。

特性如下:

1.函数名和类型相同。

当类名为A时,那么构造函数的名字也为A

2.无返回值,也不用写void。

构造函数无返回值,不需要写任何东西。

3.自动调用对应的构造函数。

在对象实例化时,编译器会自动调用对应的构造函数。

比如下面这个栈,当定义一个对象时就可以不用再调用初始化函数了。并且初始化函数Init函数就不用再存在了。
因为只要用户写了构造函数后,当对象实例化时,编译器会自动调用对应的构造函数stack(int capacity=4);

typedef int DataType;
struct stack//class可以定义一个类
{
public://访问限定符
	//构造函数---在对象实例化时自动调用
	stack(int capacity=4)//缺省值
	{
		cout << "stack(int capacipty=4)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	void Pop()
	{
		if (Empty())
		{
			return;
		}
		--_size;

	}
	void Destroy()
	{
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}
private://访问限定符
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity * 2;
			DataType* temp =(DataType*)realloc(_array, sizeof(DataType) * newcapacity);
			if (temp == NULL)
			{
				perror("realloc");
		    }
			_array = temp;
			_capacity = newcapacity;
		}
	}
private://访问限定符
	DataType* _array;
	int _capacity;
	int _size;
};

int main()
{
	stack s;//定义一个对象
    //不需要再调用初始化函数了,因为当对象实例化时,编译器会自动调用对应的构造函数stack
	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Push(4);
	s.Push(5);
	printf("%d\n", s.Top());
	printf("%d\n", s.Size());
	s.Pop();
	s.Pop();
	printf("%d", s.Top());
	s.Destroy();
	return 0;
}

用户没有调用,最后照样可以使用。
在这里插入图片描述

4.构造函数可重载

为什么?—因为可能有多种初始化方式

class Data
{
public:
    //构造函数1--带参
	Data(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//构造函数2--无参
	Data()
	{
	cout<<"xiao tao"<<endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
   Data d1;//对象实例化自动调用,但是调用的是无参的构造函数
   Data d2(2023,5,1);//对象实例化自动调用,调用的是带参的构造函数。
}

要注意,如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就跟函数声明一样了,编译器无法识别这是创建对象还是函数声明呢。
比如这样是错误的:

Data d1(void);//构造函数虽然无参,但对应的对象后面不要带括号!

5.编译器的无参构造

如果类中没有显示的定义构造函数,也就是用户没有写构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显示的定义了(也就是用户自己写了构造函数),则编译器不再生成。

第一种:用户自己写了构造函数,则编译器不会再生成。

class Data
{
public:
    //构造函数1--带参
	Data(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
   Data d2(2023,5,1);//对象实例化自动调用,调用的是带参的构造函数。
  //上面的代码是可以通过编译,因为编译器生成了一个无参的默认构造函数。
  //但是下面这个代码就不可以通过了,因为一旦显示定义了任何构造函数,编译器就不再生成构造函数了。
  Data d1;//编译器会自动调用对应的构造函数,它对应的构造函数应该是无参构造函数,但是现在用户显示定义的构造函数是带有三个参数的构造函数,所有编译会失败的。
}

它会说没有合适的构造函数可以用。
在这里插入图片描述

第二种:用户没有写构造函数,编译器将自己生成一个无参的构造函数。

class Data
{
public:

    //用户没有写构造函数,那么编译器将自动生成一个无参
    //的构造函数,当对象实例化时,编译器再自动调用这个无参的构造函数,让对象初始化。
    void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
   Data d2;//对象实例化自动调用。,调用的是编译器生成的构造函数。
   d2.Print();
}

我们可以来看下编译器生成的构造函数对成员变量到底初始化没。调用Print函数打印看下:
在这里插入图片描述

6.编译器的无参构造特性

关于编译器生成的默认成员函数,很多人会有疑惑:用户不定义构造函数的情况下,编译器会自动生成一个默认的构造函数。但是看起来好像这个构造函数没有什么用样,d对象实例化时编译器自动调用编译器生成的默认构造函数,但是d对象的三个成员变量还是随机值呀。难道说编译器生成的默认成员函数真的没有用吗?
下面应该严格初始化为0.

在这里插入图片描述

其实并不是。
C++将类型分成内置类型和自定义类型,内置类型就是语言自己提供的数据类型如int,char double 指针*类型的都是内置类型。
自定义类型就是我们使用class/struct/union等自己定义的类型。
而C++编译器生成的默认成员函数对这两种类型的初始化处理是不同的。这也就造成有时看起来编译器生成默认成员函数没有用,因为它对不同的类型处理不同。

C++编译器生成的默认成员函数对内置类型的成员变量是不做初始化处理。
对自定义类型的成员变量做初始化处理。

也就是,我们如果不写构造函数,编译器会生成默认构造函数,内置类型不做处理,自定义类型会去调用他的默认构造函数。

class Data
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//内置类型
	int _year;
	int _month;
	int _day;
	//自定义类型
	stack _st;
	

};
int main()
{
	
	Data d1;
	d1.Print();
}

都没有写构造函数,编译器将自动生成构造函数。
我们来看看编译器生成的默认构造函数对内置类型和自定义类型分别做了什么处理。在这里插入图片描述
总结一下:
1.一般情况下,有内置类型成员,就需要自己写构造函数了,不能用编译器自己生成的。
2.全部都是自定义类型成员,就可以考虑让编译器自己生成。
比如说:【用栈实现队列】
就不用写构造函数了,因为默认构造函数会完成两个栈对象的初始化。

7.声明时可缺省

其实应该让默认成员函数都一视同仁,不要搞什么类型歧视啥的,不管内置类型还是自定义类型都给他初始化多好,但是规则就摆在哪里,我们这些使用者必须遵守,但又难受的一批。你要初始化就都初始化,初始一部分是啥意思。
所以C++中针对内置类型成员不初始化的缺陷,又打了补丁。
即:允许内置类型成员变量在类中声明时可以给缺省值。

class Data
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//内置类型
	//C++对内置类型不初始化的缺陷,打了补丁
	//在类中声明变量时可以给缺省值
	//这里给的是默认的缺省值,给编译器默认生成的构造函数用的
	int _year=1;//注意:这时成员变量的声明不是定义
	int _month=1;//给缺省值即默认值
	int _day=1;
	//自定义类型
	stack _st;
	

};
int main()
{
	
	Data d1;  
	d1.Print();
}

注意:这时成员变量的声明不是定义。
这里给的是默认的缺省值,给编译器默认生成的构造函数用的。
当显示的初始化对象了,缺省值就没有用。(写了构造函数)
在这里插入图片描述
这里再总结一下:

1.一般情况下都需要写构造函数的。
2.下面这两种情况可以不写构造函数
a.有内置类型,但给了缺省值,并且缺省值符合初始化要求。
b.全是自定义类型,不需要自己写。

8.构造函数的调用

构造函数的调用很特殊。

class Data
{
public:
	//构造函数1--无参
	Data()
	{

	}
	//两个函数构成重载
	Data(int year, int month, int day)//构造函数2--带参
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//内置类型
	int _year=1;
	int _month=1;
	int _day=1;
	//自定义类型
	stack _st;

};
int main()
{
	
	Data d1;//会自动调用无参构造函数
	Data d2(2023,5,1);//会自动调用有参构造函数

	d1.Print();
	d2.Print();
	d1.Print();
}

注意这个个构造函数的调用与下面正常函数的调用有何区别?
正常函数调用都是函数+参数列表
而构造函数的调用是 对象 /对象+成员列表
是不是很奇怪,而且更奇怪的是,当调用无参构造函数时,你只能写对象,对象后面不能带括号,也就是成员列表,即使是空的,也不能写。比如这样:Data d3();
因为这样写会和函数声明有些冲突。编译器无法识别这是对象调用构造函数呢?还是函数声明呢?

9.默认构造函数

我们知道在函数传参时,可以给缺省值,缺省值又有全缺省和半缺省,所以这里面我们给构造函数全缺省或者半缺省是不是很舒服呀。当对象调用构造函数的时候可以给不给参数,也可以给一个参数,也可以给两个参数,也可以给三个参数。就存在多种调用方式,可以满足多样需求。

Data()//无参--构造函数
	{
    
	}
	//两个函数构成重载
	Data(int year=1, int month=1, int day=1)//构造函数2--带参--全缺省
	{
		_year = year;
		_month = month;
		_day = day;
	}

那上面这两个构造函数是不是构成重载函数了。对吧
但是当调用的时候就存在不合理的地方:无参调用存在歧义。
当无参调用构造函数,那编译器会选择哪个构造函数呢?这两个构造函数都可以呀,所以就造成歧义,编译器无法判断使用哪个构造函数,所以这两种形式不能同时存在。

1.函数构成重载
2.但无参调用存在歧义

在这里插入图片描述
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
即不传参就可以调用的就是默认构造函数。
注意:无参构造函数,全缺省构造函数,我们没有写编译器自己生成的构造函数,都可以认为是默认构造函数。这三种只能存在一种。

②.析构函数

Ⅰ.概念

析构函数:与析构函数功能相反,析构函数不是完成对对象本身的销毁,局部变量的销毁工作是由编译器自动完成的,对象在销毁时会自动调用析构函数,完成对象种资源的清理工作。

Ⅱ.特性

特征如下:

1.类名前+符号~。

析构函数是在类名前加上符号~。
比如类名是A
则它的析构函数则是这样写: ~A()

2.无参数也无返回值。

3.析构无重载

一个类只能有一个析构函数,因为无参数,所以无法构成重载函数

4.自动调用对应的析构函数

当对象声明周期结束时,编译器会自动调用析构函数。

typedef int DataType;
struct stack//class可以定义一个类
{
public://访问限定符
	//构造函数---在对象实例化时自动调用
	stack(int capacity=4)//缺省值
	{
		cout << "stack(int capacipty=4)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	void Pop()
	{
		if (Empty())
		{
			return;
		}
		--_size;

	}
	DataType Top()
	{
		return _array[_size - 1];
	}
	int Empty()
	{
		return _size == 0;
	}
	int Size()
	{
		return _size;
	}
	~stack()//析构函数--在对象生命周期结束时,编译器会自动调用析构函数
	{
		cout << "~stack()" << endl;
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}

private://访问限定符
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity * 2;
			DataType* temp =(DataType*)realloc(_array, sizeof(DataType) * newcapacity);
			if (temp == NULL)
			{
				perror("realloc");
		    }
			_array = temp;
			_capacity = newcapacity;
		}
	}
private://访问限定符
	DataType* _array;
	int _capacity;
	int _size;
};

析构函数和构造函数都是由编译器自动调用的。比如定义一个对象时,当对象生命周期结束时,编译器会自动调用析构函数。

int main()
{
	stack s;//定义一个对象
	//当对象生命周期结束时会自动调用析构函数
	return 0;
}

在这里插入图片描述

5.编译器的析构特性

当用户自己不写析构函数,则编译器会自动生成默认析构函数。那编译器自动生成的析构函数会做什么呢?
跟构造函数类似。析构函数不会对内置类型清理,只对自定义类型清理。

1.对内置类型不去处理。
2.自定义类型会去调用它的析构函数

注意:这里清理的都是动态开辟的,在栈上开辟的静态空间不需要我们手动销毁,全局变量,和静态变量在程序结束后就自动销毁了所以不需要管他们,只需要清理在堆上动态开辟的资源即可。

所以说我们如果不自己写析构函数的话,让编译器生成的析构函数处理,很有可以会造成内存泄漏,因为它不对内置类型清理空间。

所以总结一下什么情况下需要写析构函数,什么情况下不需要写析构。

  • 1.一般情况下,有动态生气资源的,就需要自己显示写析构函数。
  • 2.没有动态申请资源的就不需要写析构。
  • 3.需要释放资源的成员都是自定义类型,不需要写析构函数。

第一种情况:有动态资源,需要自己写的

typedef int DataType;
struct stack//class可以定义一个类
{
public://访问限定符
	stack(int capacity=4)//缺省值
	{
		cout << "stack(int capacipty=4)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		_capacity = capacity;
		_size = 0;
	}
	
	~stack()
	{
		cout << "~stack()" << endl;
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}
private://访问限定符
	DataType* _array;
	int _capacity;
	int _size;
};

int main()
{
	stack s;//定义一个对象
 }

在这里插入图片描述

第二种情况:没有动态资源,不要自己写。

class Data
{
public:
	Data(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	}
private:
	int _year;
	int _month;
	int _day;

};

第三种情况:需要释放资源的成员全是自定义类型,不需要自己写。

class Queue
{
public:

private:
	stack st1;
	stack st2;
};
int main()
{
	Queue q;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

进程控制下篇

进程控制下篇 1.进程创建 1.1认识fork / vfork 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程 #include<unistd.h> int main() {pid_t i fork;return 0; }当前进程调用fork&#xff0c;…

【VScode】的 安装--配置--使用(中文插件下载不了怎么办?)

&#x1f58a;作者 : D. Star. &#x1f4d8;专栏 : VScode &#x1f606;今日分享 : ”兰因絮果“是世间定律吗&#xff1f; 一段美好爱情开始时你侬我侬、缠缠绵绵&#xff0c;最后却以相看两厌结尾&#xff0c;让人唏嘘。清代词人纳兰容若于是咏出「人生若只如初见&#xff…

后端程序员的前端必备【Vue】 -01 Vue入门

Vue概述与基础入门 1 Vue简介1.1 简介1.2 MVVM 模式的实现者——双向数据绑定模式1.3 其它 MVVM 实现者1.4 为什么要使用 Vue.js1.5 Vue.js 的两大核心要素1.5.1 数据驱动![请添加图片描述](https://img-blog.csdnimg.cn/963aca7d7a4447009a23f6900fdd7ee1.png)1.5.2 组件化 2 …

系统集成项目管理工程师 笔记(第13章 项目合同管理)

文章目录 13.2.1 按信息系统 范围 划分的合同分类 4451、总承包合同2、单项工程承包合同3、分包合同 13.2.2 按项目 付款方式 划分的合同分类 4461、总价合同2、成本补偿合同&#xff08;卖方有利&#xff09;3、工料合同 13.3.1 项目合同的内容 44713.3.2 项目合同签订的注意事…

进程地址空间与页表方面知识点(缺页中断及写时拷贝部分原理)

谢谢阅读&#xff0c;如有错误请大佬留言&#xff01;&#xff01; 目录 谢谢阅读&#xff0c;如有错误请大佬留言&#xff01;&#xff01; 抛出总结 开始介绍 发现问题 进程地址空间&#xff08;虚拟地址&#xff09; 页表 物理内存与进程地址空间映射 缺页中断基本…

Linux操作系统之mysql数据库简介

文章目录 数据库的介绍有关数据库的操作有关数据表的操作C语言访问mysql事务视图索引 数据库的介绍 mysql数据库模型&#xff1a; 关系型数据库与非关系型数据库&#xff1a; 关系型数据库&#xff1a;指采用了关系模型来组织数据的数据库&#xff0c;关系模型就是指二维表格模…

【PCL】—— 点云滤波

文章目录 直通滤波降采样使用统计滤波&#xff08;statisticalOutlierRemoval&#xff09;移除离群点使用条件滤波&#xff08;ConditionalRemoval&#xff09;或 半径滤波&#xff08;RadiusOutlinerRemoval&#xff09;移除离群点 在获取点云数据时&#xff0c;由于设备精度&…

Vue(组件化编程:非单文件组件、单文件组件)

一、组件化编程 1. 对比传统编写与组件化编程&#xff08;下面两个解释图对比可以直观了解&#xff09; 传统组件编写&#xff1a;不同的HTML引入不同的样式和行为文件 组件方式编写&#xff1a;组件单独&#xff0c;复用率高&#xff08;前提组件拆分十分细致&#xff09; 理…

【Fluent】Error: Model information is incompatible with incoming mesh.

一、问题背景 在原有workbench数据文件上&#xff0c;修改几何数据&#xff0c;然后重新划分网格&#xff0c;在更新网格后&#xff0c;workbench就弹出错误Error&#xff01; Model information is incompatible with incoming mesh. 因为当时并不影响我打开fluent求解器&am…

C语言数组介绍和用法

文章目录 前言一、数组的定义二、数组的大小三、数组的访问方法四、使用for循环遍历数组五、数组地址的访问方法六、二维数组七、二维数组的遍历总结 前言 本篇文章将带大家学习C语言中的数组&#xff0c;数组在C语言中是一个比较重要的点&#xff0c;大家需要好好理解并多加使…

Linux Shell 介绍及常用命令汇总

文章目录 Part.I shell 简介Chap.I 概念汇编Chap.II 命令概览 Part.II shell 常用命令大全Chap.I 关于文件和目录Chap.II 关于磁盘和内存Chap.III 关于进程调度 Reference Part.I shell 简介 Chap.I 概念汇编 下面是一些概念 shell 与 bash 的区别与联系&#xff1a;bash 是 b…

2023五一杯B题:快递需求分析问题

题目 网络购物作为一种重要的消费方式&#xff0c;带动着快递服务需求飞速增长&#xff0c;为我国经济发展做出了重要贡献。准确地预测快递运输需求数量对于快递公司布局仓库站点、节约存储成本、规划运输线路等具有重要的意义。附件1、附件2、附件3为国内某快递公司记录的部分…

从力的角度再次比较9-2分布和8-3分布

( A, B )---1*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有1个节点&#xff0c;AB各由11张二值化的图片组成&#xff0c;让A中有3个0&#xff0c;8个1.B中全是0&#xff0c;排列组合A的所有可能&#xff0c;统计迭代次数的顺序。在前面实验中得到了8-3分布的数据 A-B 迭代次数 …

孔乙己文学,满街长衫,为谁而穿?解构孔乙己文学

鲁迅先生创作《孔乙己》的背景是20世纪初期的中国社会。那时&#xff0c;中国正处于民国的初期&#xff0c;社会动荡不安&#xff0c;人民生活贫困。在这个背景下&#xff0c;鲁迅开始写作并发表了一系列揭露社会黑暗面的作品。《孔乙己》是其中之一&#xff0c;它讲述了一个被…

利用snpEff对基因型VCF文件进行变异注释的详细方法

利用snpEff对VCF文件进行变异注释 群体遗传研究中&#xff0c;在获得SNP位点后,我们需要对SNP位点进行注释&#xff0c;对这些SNP位点进行更深的了解。 snpEff是一个用于对基因组单核苷酸多态性(SNP)进行注释的软件&#xff0c;snpEff软件可以用于对VCF文件进行变异注释&#x…

VC++ | VS2017编译报错-20230428

VC | VS2017编译报错-20230428 文章目录 VC | VS2017编译报错-202304281.报错1-1.解决办法 2.报错2-1.解决办法2-1-1.做如下设置2-1-2.代码调整 1.报错 1>------ 已启动生成: 项目: NvtUSBTool, 配置: Debug Win32 ------ 1>NvtUSBTool.cpp 1>$(PRJ_ROOT_DIR)nvtusbt…

Linux文件系统权限

目录标题 文件权限文件和目录的一般权限文件的权限针对三类对象进行定义文件和目录中&#xff0c;r、w、x的作用 设置文件和目录的一般权限修改文件或目录的权限—chmod(change mode)命令权限值的表示方法—使用3位八进制数表示权限值的表示方法—使用字符串表示修改文件或目录…

视频转gif如何做?三步教你视频转gif制作

如何将视频做成gif表情包呢&#xff1f;想要把视频中的精彩画面截取出来做成gif动画表情&#xff0c;却又不想下载软件的时候&#xff0c;该怎么办呢&#xff1f;有没有简单实用的工具呢&#xff1f; 一、什么工具能够截取视频做gif呢&#xff1f; GIF中文网作为一款专业的在…

react之按钮鉴权

使用HOC来完成 HOC&#xff1a;高阶组件&#xff0c;是React中复用组件逻辑的一种高级技巧。HOC自身不是React API的一部分&#xff0c;他是一种基于React的组合特性而形成的设计模式。 作用&#xff1a;用于复用组件的业务逻辑 VUE mixinReact Hoc 用户数据渲染带操作按钮渲…

C#手术麻醉临床信息系统源码,实现体征数据自动采集绘制

手麻系统源码&#xff0c;自动生成电子单据 基于C# 前端框架&#xff1a;Winform后端框架&#xff1a;WCF 数据库&#xff1a;sqlserver 开发的手术麻醉临床信息系统源码&#xff0c;应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进…