C++入门

面向对象

C++程序执行的时候,将内存大致分为四个区域:

  • 代码区:写的所有代码或中文注释
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器来管理分配释放,存放函数参数值,局部变量
  • 堆区:由程序员分配释放,若没释放则程序结束时由操作系统回收

意义:

         不同区域存放的数据,赋予不同的生命值,给我们更大的灵活编程

程序运行前:

代码区特点:共享 只读。

全局区:该区域的数据在程序结束后由操作系统来管理释放。

C++的引用

作用:给变量起别名

语法:数据类型 &别名 = 原名

引用必须初始化,一旦初始化就不可以改变。 

引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参。

优点:可以简化指针修改实参

#include <iostream>
using namespace std;

//值传递
void myswap1(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;

	//cout << "值传递后 a = " << a << "值传递后 b = " << b << endl;
}
//地址传递
void myswap2(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;

	//cout << "地址传递后 a= " << a << "地址传递后 b= " << b << endl;
}
//引用传递
void myswap3(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;

	//cout << "引用传递后 a= " << a << "引用传递后 b= " << b << endl;
}

int main()
{
	int a = 10, b = 20;
	cout << "初始化 a: " << a << "初始化 b: " << b << endl;
	myswap1(a, b);
	cout << "值传递 a = " << a << "值传递 b = " << b << endl;
	a = 10;
	b = 20;
	myswap2(&a, &b);
	cout << "地址传递 a= " << a << "地址传递 b= " << b << endl;
	a = 10;
	b = 20;
	myswap3(a, b);
	cout << "引用传递 a= " << a << "引用传递 b= " << b << endl;

	system("pause");
	return 0;
}

引用做函数的返回值

返回静态变量引用可以用作函数左值

#include <iostream>
using namespace std;

//静态变量引用返回
int  &coraline()
{
	static int a = 10;
	return a;
}

int main()
{
	int& ref = coraline();
	cout << "ref = " << ref << endl;
	cout << "ref = " << ref << endl;
    
	coraline() = 1000;//如果函数的返回值是一个引用,那么这个函数调用可以作为左值。
	cout << "ref = " << ref <<endl;
	cout << "ref = " << ref << endl;

	system("pause");
	return 0;
}

引用的本质

引用的本质在C++的内部实现是一个指针常量

相当于 int * const ref =&a;

即一旦初始化后, 就不可以发生改变。

主要使用为 int a=20;

int &ref=a;

即 ref =20;

函数高级

函数的默认参数

C++中函数的形参是可以有默认值的

 函数占位参数

C++ 中函数的形参列表里可以有占位参数,用来占位,调用函数时必修填补该位置。

 函数重载

作用:函数名可以相同,提高复用性。

条件:1.必须在同一个作用域下

2.函数名称相同

3.函数参数类型不同2,或者个数不同,顺序不同

注意:函数的返回值不可以做为函数重载条件

类和对象

1.封装

封装作为c++面向对象三大特性之一

封装的意义:

  • 将属性和行为作为一个整体,表现生活中的事物。
  • 对属性和行为加以权限设置

语法:class ***

与结构体有点相似,但是默认的访问权限不同class默认私有

struct默认权限是public

1.设计一个较为简单的类

#include <iostream>
using namespace std;

const double PI = 3.14;

class circle
{
	//访问权限
public:
	//属性
	int m_r;
	//行为(一般用函数来设置)
	double calculate()
	{
		return 2 * PI * m_r;
	}

};


int main()
{
	//通过 class circle 来创建一个具体的圆(对象),并且赋值
	circle c1;
	c1.m_r = 10;

	cout << "圆的周长: " << c1.calculate() << endl;

	system("pause");
	return 0;
}
//总结:我们通过圆类来创建一个对象,然后对于对象的属性进行赋值,访问对象的行为,获取对象的内容。
//实例化:通过一个类来创建一个对象的过程。

2.访问权限

三种访问权限

  • 公共权限: 成员 类内可以访问 类外可以访问
  • 保护权限: 成员 类内可以访问 类外不可访问(与私有权限区别在于继承里面)
  • 私有权限: 成员 类内可以访问 类外不可访问
#include <iostream>
using namespace std;
#include <string>
class person
{
public:
	string m_name;

protected:
	string m_car;

private:
	int m_password;

public:
	void func()
	{
		m_name = "coraline";
		m_car = "bus";
		m_password = 123456;
	}


};

int main()

{
	person p1;
	p1.m_name = "hh";//只可以访问名字,因为权限设置是public。

	system("pause");
	return 0;
}

3.成员属性私有化(设置读写状态)

#include <iostream>
using namespace std;
#include <string>

//设置私有可以控制自己的读写权限
class person
{
public:
	//先将属性全部私有化,然后分开设置
	//设置名字为可读可写
	void setname(string name)
	{
		m_name = name;
	}
	string getname()
	{
		return m_name;
	}
	//设置年龄可读可写
	void setage(int age)
	{
		if (age < 0 || age >150)
		{
			cout << "你这个老妖怪" << endl;
			return;
		}
		m_age = age;
	}
	int getage()
	{
		m_age = 0;
		return m_age ;
	}
	//设置lover可写
	void setlover(string lover)
	{
		m_lover = lover;
	}
private:
	string m_name;

	int m_age;

	string m_lover;
};

int main()
{
	person p;
	p.setname("coraline");                     //写
	cout << "姓名: " << p.getname() << endl;  //读
	p.setage(100);                             //写
	cout << "年龄: " << p.getage() << endl;   //读
	p.setlover("taylor");                      //不可访问只能设置。
	system("pause");
	return 0;
}

4.对象设置

构造函数:作用在于创造对象时为对象的属性赋值,编译器自动调用

  • 没有返回值也不写void
  • 函数名与类名相同
  • 构造函数可以有参数,因此可以发生重载
  • 只会调用一次

析构函数:对象销毁前系统自动调用,执行清理作用。

  • 没有返回值也不写void
  • 函数名与类名相同,在名称前面加~
  • 只会调用一次
#include <iostream>
using namespace std;
#include <string>


class person
{
	//构造函数
public:
	person()
	{
		cout << "person 构造函数的调用" << endl;
	}
	//析构函数(对象销毁了才会调用)
	~person()
	{
		cout << "person 析构函数的调用" << endl;
	}
};
//构造和析构都是必须有的实现
void test01()
{
	person p;//局部变量在栈上,执行完毕后会释放。
}
int main()
{
	test01();

	system("pause");
	return 0;
}

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

构造函数

按参数分类:有参构造  无参构造(默认构造函数)

按类型分类: 普通构造函数  拷贝构造函数

#include <iostream>
using namespace std;
#include <string>

class person
{
public:
	person()
	{
		cout << "person 无参构造函数的调用" << endl;
	}
	person(int a)
	{
		age = a;
		cout << "person 有参构造函数的调用" << endl;
	}
    //拷贝构造函数
	person(const person &p)
	{
		cout << "person 拷贝构造函数的调用" << endl;
		age = p.age;//将传入的人身上的所有属性,拷贝上来。
	}
	~person()
	{
		cout << "person 析构函数的调用" << endl;
	}
	int age;
};
//调用上面几种函数
void test01()
{
	//括号法
	person p;//默认构造函数的调用。
	person p2(10);//有参构造函数。
	person p3(p2);//拷贝构造函数调用。

	//显示法
	person p;
	person p2 = person(10);//有参构造
	person p3 = person(p2);//拷贝构造

	//隐式转换法
	person p4 = 10;//相当于person p4 = person (10);有参构造
	person p5 = p4;//拷贝构造

}

int main()
{
	test01();
	system("pause");
	return 0;
}

上图为几种定义与调用的方法

 拷贝构造函数的调用场景

  1. 用一个已经创建完毕的对象来初始化一个新对象
  2. 值传递的方式给函数参数传递
  3. 以值方式返回局部函数

6.构造函数的调用规则

每当我们创建一个类的时候,C++ 编译器至少给一个类添加3个函数

  默认构造函数,析构函数,拷贝函数(对属性进行值拷贝)

调用规则:

        若用户定义有参构造函数,C++会提供默认拷贝函数(不提供无参构造)

  若用户定义拷贝构造函数,C++不会再调用其他构造函数

7.深拷贝与浅拷贝

浅拷贝:简单的赋值拷贝操作

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

注意:如果属性又在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题。

释放的顺序是先进后出,所以P2会先被释放,而P2访问的是P1的拷贝构造,但是被释放了,P1就不能对NULL进行访问释放。

#include<iostream>
using namespace std;

class person
{
public:
	person()
	{
		cout << "person 的默认构造函数调用" << endl;
	}
	person(int age  , int height)
	{
		m_age = age;
		m_height = new int (height);
		cout << "person的有参构造函数调用" << endl;
	}
	//自己实现拷贝函数,解决浅拷贝带来的问题
	person(const person& p)
	{
		cout << "拷贝构造函数的调用" << endl;
		m_age = p.m_age;
		//m_height = p.m_height;(这行是编译器默认的实现代码)
		//下面进行深拷贝操作

		m_height = new int(*p.m_height);//让自己的这个指向新的内存。
	}
	~person()
	{
		//析构代码,将堆区开辟的数据做释放操作
		if (m_height != NULL)
		{
			delete m_height;
			m_height = NULL;
		}
		cout << "person的析构函数调用" << endl;
	}
	int m_age;
	int *m_height;//加一个指针指向身高(把这个开辟到堆区)
};

void test01()
{
	person p1(18,160);

	cout << "p1的年龄为: " << p1.m_age << "身高为: "<<*p1.m_height <<endl;
	person p2(p1);
	cout << "p2的年龄为: " << p1.m_age << "身高为: " << *p2.m_height << endl;

    

}
int main()
{
	test01();

	system("pause");
	return 0;
}

 8.初始化列表

作用:对类中的属性进行初始化操作

 

 9.类对象作为类成员

C++类中的成员可以是另一个类的对象,这个成员被称作对象成员

有点类似与C语言中的结构体嵌套结构体

 10.静态成员

静态成员分类

1.静态成员变量

           所有对象共享一份数据

           在编译阶段分配内存,类内声明,类外初始化

2.静态成员函数

           所有对象共享同一个函数

           静态成员只能访问静态成员变量

 

 C++对象模型和this指针

1.成员变量和成员函数分开储存

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShasHashALU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值