【C++基础】类和对象(重要知识点)封装;静态成员;构造和析构;this指针 ;友元friend;继承,多态

 

🍉内容专栏:【C/C++要打好基础啊】

🍉本文脉络:封装;静态成员;构造和析构;C++对象模型和this指针 ;友元friend;继承;多态

🍉本文作者:Melon西西

🍉发布时间 :2023.1.30

目录

1.面向过程和面向对象的认识:

1.1. C++兼容C结构体的用法,同时struct在C++中也升级成了类

1.2.给成员变量初始化和打印:(后面4.5有优化)

 2.封装:

2.1.访问限定符

  3.静态成员:及再成员变量和成员函数前加上关键字static

 4.类的六个默认成员函数

4.1构造函数:

 4.2析构函数~:完成对象中资源的清理

 4.3拷贝构造

4.4函数名operator操作符

 4.5初始化列表初始化属性

4.6类对象作为成员

析构的时候先释放(析构)Person,再析构phone

  5.C++对象模型和this指针

 练习:​编辑

6.友元:friend 的三种实现:

6.1.全局函数作为友元

6.2.类做友元:

  6.3.成员函数做友元:

7.继承:减少重复的代码

7.1语法:

7.2继承方式:公共继承,保护继承,私有继承(继承默认私有继承)

7.3.继承后的析构和构造顺序:

7.4.继承中同名成员处理方式:

 同名成员属性和同名成员函数方法一样:

继承同名静态成员处理方法:

 7.5多继承语法:(实际情况慎用)

 8.多态


1.面向过程和面向对象的认识:

1.1. C++兼容C结构体的用法,同时struct在C++中也升级成了类

面向过程关注把实际问题转化为代码执行的方法

面向对象关注的是类对象及类对象间的关系

Fruit叫做类;f1,f2叫做对象

1.2.给成员变量初始化和打印:(后面4.5有优化)

注意,用成员方法初始化,char形前面必须有const修饰,形参必须为const char *,int不用。

初始化时,char形字符串要用strcpy,int 直接赋值,记住喽!!!

strcpy和strcpy_s需要包含头文件#include<cstring>

在编译的时候如果报错说strcpy不安全C4996,则用strcpy_s(_a,a)拷贝用法一样。

 

打印成员函数:

 2.封装:

数据和方法都放到了一起在类里面,封装是一种更好的管理

面向对象三个特性:封装、继承、多态

2.1.访问限定符

public 共有,可以直接访问

protected 保护,不可以直接访问

private 私有,不可以直接访问

class的默认访问权限为privte

struct的默认访问权限为public(这也是二者的区别)

建议在定义类的时候要明确定义访问限定符,不要用默认的

用法如下:

作用范围:到下一个访问限定符,没有就默认到类结束

注意:善用类域对成员方法(成员函数)进行操作

  3.静态成员:及再成员变量和成员函数前加上关键字static

静态成员变量:所有对象共享同一份数据,在编译阶段分配内存,类内声明,类外初始化

静态成员函数:所有对象共享同一个函数;静态成员函数只能访问静态成员变量,不可访问非静态成员变量。它也是有访问权限的。

Person()
{
public:
    static int _A;   //类内声明
};
int _A = 100;        //类外初始化
void test()
{
  Person p ;
  cout<<p._A<<endl;    //结果是100
  Person p2 ;
  p2._A =200;
  cout<<p._a<<endl;    //这里输出的还是_A,但结果是200,共享一份数据
}

 静态成员变量不属于某个对象,因为所有对象都共享同一份数据。它也是有访问权限的。

静态成员变量有两种访问方式:

通过对象进行访问:  cout<< _A  <<endl;

通过类名进行访问: cout<< Person :: _A <<endl;

 4.类的六个默认成员函数

 如果我们不实现,编译器会自己生成

4.1构造函数:

构造函数不是开空间创建对象,二十初始化对象。

构造函数不能有返回值,不用写void;

函数名与类名相同;构造函数可以有参数,可以发生重载;

在创建对象的时候构造函数会自动调用,而且只会调用一次。

 4.2析构函数~:完成对象中资源的清理

类对象需要资源的清理(开辟了动态资源)才需要自己写析构函数,其他的不用自己实现析构函数。

析构函数名实在类名前面加上字符~

析构函数没有参数没有返回值;

一个类有且只有一个析构函数。

class Person()
{
public:
   Person()
   {
    cout<<"Person构造函数的调用"<<endl;
   }
   ~Person()
   {
    cout<<"Person析构函数的调用"<<endl;
   }
}
void test1()
{
   Person();
}

如果上述没有写在test1而是写在main函数中

那么析构函数会return 0 后在按任意键后面闪一下子

如果 d1比d2先构造,但是d2比d1先析构

 4.3拷贝构造

浅拷贝:编译器提供的拷贝,比如等号赋值。如下;p1和p2年龄都是18,浅拷贝。

浅拷贝可能带来的问题是堆区的内存重复释放,这个问题要利用深拷贝进行释放。

深拷贝:在堆区重新申请空间,进行拷贝操作

参数必须是引用,否则造成无限递归。

4.4函数名operator操作符

函数名算子操作符,返回类型看操作符运算后返回值是什么

操作符有几个操作数,他就有几个参数

返回类型看操作符运算后返回值是什么//参数,操作符有几个操作数,他就有几个参数


如果对两个类进行加减比大小等操作,就需要用运算符重载。

比较两个结构体日期大小:

 

 4.5初始化列表初始化属性

Person (int a,int b, int c) : m_A(a,m_B(b),m_C(c) 
{
}
test()
{
    Person p (10,20,30);
}

4.6类对象作为成员

C++类中的成员可以是另一个类的对象,我们程该成员为对象成员

 在下面代码中,Phone类在Person类中;当其他类对象作为本类对象,先构造其他类对象,再构造自身,及先构造Phone,再构造Person

析构的时候先释放(析构)Person,再析构phone

class Person
{
Public:
       //Phone _Pname =Pname
       Person(int age,string Pname) : _age(age) ,_Pname(Pname)  //初始化列表的方式赋值
       {
       }
       int _age;
       Phone _Phone;
} ;
class Phone
{
public:
       Phone(string Pname)
       {
        _Pname=Pname
       }
       string _Pname;
}  ;
void test1()
{
  Person p(10,"vivo" );
}

  5.C++对象模型和this指针

在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上

空对象占空间内存为1,sizeof(p)=1

此时p占空间内存为4,sizeof(p)=4,后两个不属于类的对象上。 

this指针指向被调用的成员函数所指的对象

this指针是隐含在每一个非静态成员函数内的一种指针,不需要定义,直接使用。

 在Print()函数中,()里隐藏了this指针,类型是Fruit * this

  f1.Print()中,()里隐藏了&f1

struct Fruit
{
	char _name[20];
	int _number;
	char _colour[20];

	void Init(const char * name, int  number, const char * colour)
	{
		strcpy_s (_name, name);
		_number =  number;
		strcpy_s (_colour, colour);
	}
	void Print()
	{
		cout << _name << _number << _colour << endl;
	}
};
void fruit()
{
	struct Fruit f1;  //兼容C
	Fruit f2;         //升级到类
	f1.Init("苹果", 10, "红色");
	f2.Init("香蕉", 6, "黄色");
}

this指针代表了当前对象,能够区分每个对象的自身数据,保证每个对象拥有自己的数据成员,但共享处理这些数据的代码。

this指针是非静态成员函数的隐含形参,每个非静态的成员函数都有一个this指针。

this指针在非静态的成员函数里面,对象不存在,this指针可以为空。

用途:当形参和成员变量同名时,可用this指针来区分。

在类的非静态成员函数中返回对象本身,可使用return *this

 练习:

 编译器报错是语法错误,空指针不会编译报错,对空指针解引用会运行崩溃。

6.友元:friend 的三种实现:

6.1.全局函数作为友元

 void goodGay()函数为全局函数,只需要把函数复制到类里面,前面加friend即可,不需要放public里

6.2.类做友元:

核心:   friend class Goodboy;

#include<iostream>
using namespace std;
class Building
{
	//这样Goodboy就可以访问Building(本类)里的私有成员了
	friend class Goodboy;
public:
	Building();

	string _Sittingroom;
private:
	string _Bedroom;
};
class Goodboy
{
public:
	Goodboy()
	{   //这里注意Building类一定要在Goodboy的上面,不然找不到Building
		building = new Building; 
	}
	Building * building;
	void visit()
	{
		cout << "访问" << building->_Sittingroom << endl;
		//卧室是类的私有成员,不可以访问,加友元后才可以访问
		cout << "访问" << building->_Bedroom <<endl;
	}
};
//放在类外写函数的写法:
Building::Building()
{
	_Sittingroom = "客厅";
	_Bedroom = "卧室";
}
int main()
{
	Goodboy ming;
	ming.visit();
	return 0;
}

  6.3.成员函数做友元:

目的:让B类的成员函数void visit()能够访问A类里面私有权限里的内容

声明方法:在想被访问的A类里面写:friend void  B:: visit();

7.继承:减少重复的代码

7.1语法:

class 子类 :  继承方式   父类    子类也叫派生类,父类也叫基类

class A : public B;

下级别的类除了有上面级别的共性,还有了自己的特性。 ,利用继承来减少重复代码。

7.2继承方式:公共继承,保护继承,私有继承(继承默认私有继承)

 继承后子类里有自身的+父类的所有成员,内存sizeof(子类)是一共的内存,只不过不能访问的编译器会隐藏掉访问不到,还是会继承下去的。

7.3.继承后的析构和构造顺序:

继承中先调用父类的构造,再调用子类的构造。先析构子类,后析构父类。继承于析构顺序相反。

7.4.继承中同名成员处理方式:

子类对象访问子类同名成员:直接访问即可

子类对象访问父类同名成员:需要加作用域

子类与父类拥有同名的成员函数时,子类会隐藏掉父类中同名成员函数,加作用域可以访问

 同名成员属性和同名成员函数方法一样:

如果父类和子类都有同名成员变量_a,在继承后的子类中取_a默认是子类的_a

想取父类中的_a要加作用域  s.Fulei::_a

继承同名静态成员处理方法:

静态成员可以通过类名和通过对象两种方式来访问。

通过对象的方式访问同上,需要加父类作用域才能访问父类,默认子类

通过类名访问父类:Son::Fulei::_a  通过类名访问子类 Son::_a

 7.5多继承语法:(实际情况慎用)

C++允许一个类继承多个类

语法:  class子类:继承方式 父类1,继承方式  父类2

 8.多态

静态多态:函数重载,运算符重载。函数地址早绑定,编译阶段确定函数地址。

动态多态:派生类和虚函数实现运行时多态函数地址晚绑定,运行阶段确定函数地址

 动态多态满足条件:

要有父类和子类,子类继承父类;

子类要重写父类的虚函数(虚函数:virtual void .....)

重写:函数返回值类型,函数名,参数列表完全相同

动态多态使用:弗雷德指针或者引用执行子类对象

 

 

 


写在最后:

博主大一学识尚浅,内容仅供参考,欢迎大家在评论区交流分享。

以后会经常发关于C/C++的学习心得,感兴趣的小伙伴可以点个关注支持一下^_^

  • 41
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值