c++学习第五讲---类和对象(一)

发布时间:2023年12月29日

对象:万事万物皆为对象;

类:具有相同性质的对象,可以抽象为类。

1.封装:

1.封装的意义:

(1)将属性和行为作为一个整体,表现生活中的事物。

(2)将属性和行为加以权限控制。

注:叫法:

类中的属性和行为:统称成员

属性:又称为 成员属性、成员变量

行为:又称为 成员函数、成员方法

2.语法:

class 类名 {?访问权限 :属性 / 行为 } ;

实例化:通过一个类,创建出一个对象。

例:设计一个圆类,求圆的周长:

//设计一个圆类,求圆的周长
const double PI = 3.14;

class Circle
{
	//访问权限
public:
	//属性
	int r;
    //行为
	double C()
	{
		return 2 * PI * r;
	}
};
int main()
{
	Circle round;//实例化
	round.r = 10;
	cout << "圆的周长:" << round.C() << endl;
	return 0;
}

3.访问权限:

公共权限(public):类内可以访问,类外可以访问
保护权限(protected):?类内可以访问,类外不可以访问,子类可访问父类中保护内容
私有权限(private):?类内可以访问,类外不可以访问,子类不可访问父类中私有内容
(保护和私有在继承中有区别)

例:

class Person
{
public:
	string Name;
protected:
	string car;
private:
	int Password;
public:
	void func()
	{
		Name = "name";
		car = "car";
		Password = 1;//类内均可访问
	}
};
int main()
{
	Person p1;
	p1.Name = "zhangsan";
	p1.car = "benchi";//报错,保护和私有访问不到
	return 0;
}

4.struct和class的区别:

基本一致,但默认的访问权限不同。

struct的默认权限为公共,而class的默认权限为私有。
(默认权限,即未标明访问权限时,创建成员时的成员权限)

5.成员属性设为私有:

将成员属性设为私有,提供公共的函数来读写私有成员。

优点:
1.可以自己控制读写权限;
2.对于写,可以检测数据有效性

//人类
class Person
{
public:
	//设置姓名
	void setName(string name)
	{
		m_Name = name;
	}
	//获取姓名
	string getName()
	{
		return m_Name;
	}
	//获取年龄
	int getAge()
	{
		return m_Age;
	}
	//设置偶像
	void setIdol(string Idol)
	{
		m_Idol = Idol;
	}
	//设置年龄
	void setAge(int Age)
	{
		if (Age < 0 || Age>150)
		{
			cout << "年龄有误,写入失败" << endl;
			return;
		}
		m_Age = Age;
	}
private:
	string m_Name;//姓名 可读可写
	int m_Age = 18;//年龄 可读  也可以写但只限制在0到100(检测数据有效性)
	string m_Idol;//偶像 只写
};

2.对象的初始化和清理:

1.构造函数和析构函数:

构造函数:为对象的成员属性赋值。

析构函数:对象销毁前进行清理。

c++利用这两个函数进行对象的初始化和清理,必须有,如果程序员不实现,会由编译器自动实现,但是是空实现。(即函数中没有内容)

注:构造函数和析构函数应放在public里。

(1)构造函数:类名(){ }

1.没有返回值也不写void;
2.函数名称与类名相同;
3.构造函数可以有参数,因此可以重载;
4.构造函数会由编译器自动调用,无需手动调用。

(2)析构函数:~类名(){ }

1.没有返回值也不写void;
2.函数名称与类名相同,前加 ~;
3.构造函数不可以有参数,因此不可以重载;
4.构造函数会由编译器自动调用,无需手动调用。

2.构造函数的分类以及调用:

两种分类方式:
按参数分类:有参构造和无参构造
按类型分类:普通构造和拷贝构造

三种调用方式:
括号法,显示法,隐式转换法。

1.有参构造和无参构造:
	Person()
	{
		cout << "构造函数的调用" << endl;
	}	
	Person(int a)
	{
		cout << "构造函数的调用" << endl;
	}
2.拷贝构造函数:

传入一个对应类的引用,同时必须加const。

	Person(const Person &p)
	{
		age = p.age;
	}
3.调用:括号法:

用括号传参的方式决定用哪一种构造函数。

	//括号法
	Person p1;//默认无参构造
	Person p2(10);//有参构造
	Person p3(p2);//引用构造

注:用无参构造时不要加(),编译器会默认为函数声明,而非创建对象。

4.调用:显示法:
	//显示法
	Person p1;
	Person p2 = Person(10);//有参构造
	Person p3 = Person(p2);//拷贝构造

注:1.匿名对象,?会在本行执行后就被回收掉。

Person(10);

2.不要利用拷贝构造函数初始化匿名对象,因为会被认为是一个对象的声明,重定义报错。

Person(p3);
5.调用:隐式转换法:
	//隐式转换法
	Person p4 = 10;
	Person p5 = p4;

? ?3.拷贝构造函数的调用时机:? ? ? ? ? ? ? ? ? ? ? ? ? ??

1.使用一个已经创建完毕的对象来初始化一个新对象

void test01()
{
	Person p1(10);
	Person p2(p1);
}

2.值传递的方式给函数参数传值

void work(Person p)//拷贝构造
{

}
void test02()
{
	Person p;
	work(p);
}

4.构造函数的调用规则:

1.默认情况下,c++编译器至少给一个类添加3个函数:

(1)默认构造函数(无参,函数体为空)
(2)默认析构函数(无参,函数体为空)
(3)默认拷贝构造函数,对属性进行值拷贝(即不写拷贝构造函数也有默认的)

2.如果写了有参构造函数,编译器就不再提供默认构造函数,但依然有拷贝构造。
? 如果写了拷贝构造函数,编译器就不提供其他普通构造函数了。

无参 < 有参 < 拷贝

class Person
{
public:	
	Person(int a)
	{
		cout << "Person有参构造函数调用" << endl;
	}		
	~Person()
	{
		cout << "Person析构函数调用" << endl;
	}
	int m_age;
};
int main()
{
	Person p;//报错,不再有默认构造函数
	return 0;
}

?

文章来源:https://blog.csdn.net/2301_78922485/article/details/135262811
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。