C++中类和对象
类:就是将具有相同特征的实物进行抽象(家具类、动物类)
对象:类的实例化(桌椅凳、猫狗兔)
类的定义
- 类有两种定义方式,struct和class,但在C++中更喜欢用class。
- class为定义类的关键字,Demo为类的名字,{}中为类的主体,类定义结束时后面分号。
class Demo //class + 类名
{
//类体:由成员函数和成员变量组成
}; //类定义后的分号;特别重要
类的访问限定符
- 作用:对象对该类成员的访问限定
- 类的访问限定符有:
public:公有,所有对象在类外都可以直接访问;
protected:保护,为继承而产生的关键字;
private:私有,不能访问 - struct和class区别:class的默认访问权限是private,而struct的默认访问权限是public(因为struct兼容C语言)
class Demo
{
//默认访问权限为private
int a;
public:
int b;
protected:
int c
private:
int d;
};
类的作用域
编写类的时候,类里面的所有成员都在类的作用域中,没有访问权限一说,在类体外定义成员,需要使用 :: 作用域解析符指明成员属于哪个类域。
class Test
{
int a = 2;
int b = 3;
//访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符初出现为止
public:
int add(int x, int y)
{
int z = x + y;
return z;
}
private:
int add2()
{
add(a,b);
}
};
//使用 :: 作用域解析符指明add2属于Test类
int Test::add2()
{
cout << "两个数之和为:" << Test::add2() << endl;
}
构造函数
构造函数主要进行初始化操作,每一个对象被创建的时候都会调用构造函数进行初始化
- 特点:
函数名和类名相同;
无返回值;
对象实例化时编译器自动调用对应的构造函数;
构造函数可以重载。 - 注意:
如果没有编写构造函数,编译器会自动生成一个无参的构造函数;
每个类都有一个默认的构造函数;
默认构造函数可以全缺省构造函数和无参构造函数,但是默认构造函数只能有一个。
#pragma once //检查头文件是否被重复包含
#include<iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "默认构造函数被调用" << endl;
}
Test(int a)
{
_a = a;
cout << "构造函数被调用" << endl;
}
void print()
{
cout << _a << endl;
}
private:
int _a;
};
int main()
{
int x = 3;
Test test1;
Test test2(x);
test2.print();
system("pause");
return 0;
}
运行结果如下:
析构函数
销毁对象时会调用析构函数,也是在生命周期结束的时候用来清理资源。
- 特点:
析构函数名称是在类名前加上字符~;
无参数无返回值;
一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数;
对象生命周期结束时,C++编译系统自动调用析构函数。
#pragma once
#include<iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "默认构造函数被调用" << endl;
}
~Test() //析构函数
{
cout << "析构函数被调用" << endl;
}
};
void test()
{
Test tt; //自动调用析构函数
}
int main()
{
test();
system("pause");
return 0;
}
运行结果为:
拷贝构造函数
通过已经创建好的对象复制出一个对象。
- 特点:
拷贝构造函数是构造函数的一个重载形式;
拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用;
若未显示定义,系统自动生成默认的拷贝构造函数
#pragma once
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1997, int month = 11, int day = 14)
{
_year = year;
_month = month;
_day = day;
}
Date(Date& d) //拷贝构造函数
{
_year = d._year;
_month = d._month;
_day = d._day;
cout << "拷贝构造函数被调用" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date dd;
Date d1(dd);
system("pause");
return 0;
}
运行结果如下:
运算符重载
运算符重载时具有特殊函数名的函数,也具有返回值类型,函数名以及参数列表,其返回值类型与参数列表与普通函数类似。
函数原型: 返回值类型 operator 操作符(参数列表)
- 注意:
. (成员访问运算符)、.* (成员指针访问运算符)、:: (域运算符)、sizeof (长度运算符)、?: (条件运算符)5个运算符不能重载;
不能通过连接其他符号创建新的操作符;
#include<iostream>
using namespace std;
class Data
{
public:
Data()
{
_year = 1997;
_month = 11;
_day = 14;
cout << "默认构造函数被调用" << endl;
}
Data(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
cout << "构造函数被调用" << endl;
}
Data(Data& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
cout << "拷贝构造函数被调用" << endl;
}
//运算符重载
bool operator == (Data& d)
{
cout << "==运算符重载" << endl;
return _year == d._year&&_month == d._month&&_day == d._day;
}
void print()
{
cout << "当前日期对象为:" << _year << "年" << _month << "月" << _day << "日" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1;
d1.print();
Data d2(2020, 4, 18);
d2.print();
Data dd(d2);
dd.print();
if (d2 == d1)
{
cout << "日期相同" << endl;
}
else
{
cout << "日期不同" << endl;
}
system("pause");
return 0;
}
运行结果如下: