C++学习 自定义数据类型——类和结构体

C++的类:用户自定义的类型,将不同类型的数据和操作封装在一起

1.类的定义:

      使用class声明一个新的数据类型名称,用一对大括号封装该类型的数          据成员和成员函数,大括号末尾以分号结束。

      对象只能访问public成员,可将允许用户操作的成员定义为public访问          权限。默认情况下,成员的访问权限是private,只允许对象内部的成员访问。

class 类名 //首字母一般大写
{
    public:   //类与外界的接口 通过此操作类对象
            公有数据成员和成员函数;
    private:
            私有数据成员和成员函数;  //是默认访问权限
    protected:
            受保护的数据成员和函数;
};

类是一种类型,类本身不占内存。

当定义类的对象时,按照类定义的数据成员的定义顺序,按照数据类型依次分配内存单元。每个对象的数据成员占据独立的内存单元。类的成员函数只在被对象调用时才获得内存,调用完毕后释放内存。 

2.类的成员函数

在类的定义外部完成函数的定义

在完成定义时,要在函数名前面加上类名:: 表示类的作用域

注意:1)带默认值的参数仅使用一次,写在类的声明中,函数实现语句中不重复定义

2)参数有多个时,带默认值的参数的定义顺序是从右向左,即任何一个参数有默认值,则该参数右边的所有参数都必须有默认值

3.创建和使用对象

定义类类型之后,可以像普通数据类型一样定义类的变量,称为对象或类的实例。

对象只能访问类的公有成员,通过点(.)成员运算符访问公有数据成员

对象名.公有数据成员名

对象名.公有成员函数

可以在定义的同时进行初始化,格式为:

类型名称 对象名称=值;

类型名称 对象名称(值);

对象的初始化要依靠构造函数实现

class Student
{
	public:   
			void Set(int i_ID,char s_name[],char c_sex,int i_age);
    		//设置学生的基本信息 
			void Output();
			//输出学生的基本信息 
    		void SetAge(int i_age);
    		//设置年龄 
    		int GetAge();
    		//读取年龄 
	private:
			int ID; //学号 
			char name[21]; //姓名 
			char sex; //性别 
			int age; //年龄 
};
#include<iostream>
#include<cstring>
using namespace std;
//Student类成员函数的定义 
void Student::Set(int i_ID,char s_name[],char c_sex,int i_age)
{
	ID=i_ID;
	strcpy(name,s_name); //cstring 库函数:字符串赋值
	sex=c_sex;
	age=i_age;
}
void Student::Output()
{
	cout<<"ID:"<<ID;
	cout<<"\nName"<<name;
	cout<<"\nSex"<<sex;
	cout<<"\nAge"<<GetAge();
}
int Student::GetAge()
{
	return age;
}
void Student::SetAge(int i_age)
{
	age=i_age;
}
int main()
{
	Student stu1; //创建stu1对象,实现学生信息的输入输出 
	int id,age;
	char name[21],sex;
	cout<<"原始学生数据为:"<<endl;
	stu1.Output(); //输出stu1的相关信息,由于没有初始化,显示为随机值 
	cout<<"输入学生数据:"<<endl; 
	cout<<"ID:"<<endl;
	cin>>id;
	cin.ignore(80,'\n'); //消除上一行的多余内容,包括回车 
	cout<<"Name:"<<endl;
	cin.getline(name,20); //输入姓名,允许空格 
	cout<<"Sex(F/M)"<<endl;
	cin>>sex;//接收一个字符给性别
	cin.ignore(80,'\n');  //清除当前行(防止输入多个字符) 
	cout<<"Age"<<endl;
	cin>>age;
	stu1.Set(id,name,sex,age);//之前没有初始值,所以显示为随机值,经过赋值后,得到了输入的值 
	cout<<"结果为:"<<endl;
	stu1.Output();//输出对象信息显示具体数值 
	return 0; 
	 
}

4.构造函数和析构函数:与构造其他变量一样,在创建对象的同时可以对对象进行初始化。类的数据成员不能直接被复制,需要使用特殊的函数实现。

1)构造函数:

构造函数是类的成员函数,函数名是类名,无返回值,可以被重载。

当定义对象时,系统自动调用构造函数对数据成员进行初始化。

如果不定义构造函数,系统会提供一个默认的构造函数,默认的构造函数形式为:

类名(){ }

是一个不实现任何代码的空函数

只要定义了构造函数,系统提供的默认构造函数就无效。所以只要定义构造函数,就必须定义无参构造函数。

class Student
{
	public:   
			Student (int i_ID,char s_name[],char c_sex,int i_age);
    		//设置学生的基本信息 
			Student Output();
			//输出学生的基本信息 
    		Student SetAge(int i_age);
    		//设置年龄 
    		Student GetAge();
    		//读取年龄
};

构造函数是创建对象时自动调用的成员函数,因此必须是公有的。类提供多个构造函数满足用户创建对象时的初始化。

构造函数的实现方法与类的其他成员的函数实现方法类似:

Student::Student(int i_ID)
{
    Set(i_ID,"***",'F',10);
}

//构造函数内部与Set功能完全相同,可以直接调用Set成员函数实现:
Student::Student (int i_ID,char s_name[],char c_sex,int i_age)
{
    Set(i_ID,s_name,c_sex,i_age);

}

构造函数可以通过默认参数实现重载功能P229

2)析构函数:当对象生存周期结束时,系统自动调用析构函数释放对象的内存空间。

析构函数名师在类名前面加上波浪号(~)

析构函数没有返回值类型,没有参数,所以一个类只有一个析构函数。

系统会提供一个默认的析构函数:

~类名(){ }

//Student的默认析构函数定义:
~Student() {}
//自定义Student类的析构函数。例如:表示对象使用完要回收时执行一个输出语句的功能:
Student::~Student()
{
    cout<<"Destruction Student.\n";
}

3)对象的创建与销毁的次序

对象就是class定义的类类型的变量。创建对象时,系统为类对象的数据成员分配内存空间,然后使用析构函数对成员变量进行初始化。对象的生存周期结束(如:函数调用完毕)时,系统将自动调用析构函数清理对象所占用的内存空间,销毁对象,这个过程称为析构。

一般情况下,析构的顺序总是与构造的顺序相反,即先构造的对象后析构。

5.对象数组:定义类类型的数组

Student stuArr[30];

系统自动调用构造哦啊函数对stuArr数组中哦你的每个student对象进行初始化

结构体:在默认情况下,成员函数和数据结构都是公有的,可以通过对对象数据成员和成员函数的直接操作。

1.结构体类型的声明:

关键字 struct

结构体类型名称的首字母大写

格式:struct 类型名称

       {

     结构体数据成员定义

     };

struct Date
{
    int year;
    int month;
    int day;
};

定义的结构体类型是struct Date 而不是date

可以用typedef定义一个别名,这样,可以使变量定义简洁且移植方便

typedef struct Date
{
    int year;
    int month;
    int day;
}Date;

结构体类型内的数据成员可以是基本数据类型、数组、或以定义的结构体类型。

//定义学生结构体类型
//包含四个数据成员 学好 姓名 性别 出生日期
struct Student
{
    int num;
    string name;
    char sex;
    Date birth; //Date结构体必须定义在struct Student前面
};

 定义结构体类型后,系统不会为结构体类型分配内存。当定义结构体类型的变量时,系统会根据结构体定义时的数据成员的顺序和数据类型,依次为各数据成员分配连续的内存单元。结构体类型变量的内存大小是数据成员的内存大小之和。

××结构体的声明一般放在文件的头部。

2.结构体类型变量的定义:

(1)先声明结构体类型,再定义变量

struct Student stu1,stu2; //定义了两个struct Student类型变量stu1 stu2

(2) 在定义结构体类型的同时定义变量。在结构体定义尾部的分号前面书写变量名。

struct Date
{
    int year;
    int month;
    int day;
}birth;

(3)定义无名的结构体类型,同时直接定义结构体类型变量。由于没有结构体类型名称,因此不能在其他地方再次定义这种类型的变量。(慎用

struct
{
    int year;
    int month;
    int day;

}birth;

结构体类型的变量可以在定义时初始化:初始值是一个集合,用大括号括起来,按照结构体类型定义时的数据成员顺序及数据类型书写初始值。

struct Date date1={2016,2,10};
struct Student stu1={"1001","zhang ye ye",'F',{1999,3,6}};

3.结构体类型变量的使用:

(1)结构体类型变量的数据成员:变量名.数据成员名  (.)是结构体类型成员运算符

//输入
cout<<datel.year<<date1.month;

结构体的成员可以单独使用,也可以同普通数据类型一样进行各种运算

date1.year=1000;
stu1.name="lisi";

如果结构体成员仍然是结构体,继续使用(.)访问结构体成员

stu1.birth.year=1991;

(2)结构体类型变量的整体赋值:

具有相同成员类型的结构体类型变量可以整体和相互赋值

struct Student stu3=stu1;
//等价于
struct Student stu3;
stu3=stu1;

当函数的形参变量是结构体类型或引用时,调用函数时可以直接传递同类型的结构体变量。

4.结构体类型的数组:struct Student stu[30];

对每一个元素进行初始化,每个元素的初始值用一对大括号括起来,一般每个元素的初始值占一行

结构体与类的比较

1.C语言的结构体/类与C++语言的区别 P243--P244

数据类型的别名:typedef 数据类型 别名

typedef int INT;
//代码兼容性和扩展性 用INT表示int 以后需要修改为long类型时 只需要修改typedef语句

type struct Date
{
    int year;
    int month;
    int day;
}Date;
//对复杂数据类型取精简别名,可以直接使用Date

枚举类型:还没有看 244--241

C++的string类:还没有看247--251

 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值