KZY------C++习题----2------2023-01-11/12

核心编程二

1 内存分区模型

1.1 程序运行前

1.2 程序运行后

1.3 new操作符

2 引用

2.1 引用的基本使用

#include <iostream>
using namespace std;
int main() {
    
    

   int this_a =10;
   int &b=this_a;

   cout<<"this_a: "<< this_a<<endl;
   cout<<"b: " << b<<endl;
   cout<<"&b: " << &b<<endl;

}

引用的用法

int a;
int *p=&a;//指针有自己的指针名字和地址,存储了指向对象的地址(可以更改→指向别的对象的地址)
int &b=a;//引用即别名(一旦声明则不可变更) 引用b和被引用的a用同一个地址:符号表中2个变量名指向同一个地址int &b=a和int* const pp=&a;一样不能改变指向的对象,但能改变指向对象的值)
//不同在于b的地址就是a的地址       即&b == &a
//而pp有自己的地址 pp存放了a的地址 即pp == &a
符号表存放内容:	变量名	变量地址     【符号表生成后不再改变】
int a			a		a的地址
指针p:			指针名	指针地址    而指针指向的a地址(存放的数据)可以改变		【不安全】
引用b:			引用名b	引用对象a的地址→→→故引用对象不能改变		【安全】

2.2 引用注意事项

  • 引用必须初始化
  • 引用在初始化后,不可以改变

2.3 引用做函数参数

#include <iostream>
using namespace std;

void func_swap_m(int m,int n)//值传递
{
    
    
      int temp = m ;
      m = n;
      n = temp;
}
void func_swap_y(int *m,int *n)//地址传递 指针
{
    
    
      int temp = *m ;
      *m = *n;
      *n = temp;
}
void  func_swap_z(int & m, int& n) {
    
     //引用传递
	int temp = m;
	m = n;
	n = temp;
}
 //&取地址符号和引用有什么区别
int main() {
    
    

   int a1 = 4.5;
   int a2 = 7;
   int &b1 = a1;
   int &b2 = a2;

   func_swap_m(a1,a2);
   cout<<"c_m: "  <<endl;
   cout<<"a1: "<< a1 <<endl;
   cout<<"a2: "<< a2 <<endl;
   cout<<"" <<endl;


   func_swap_y(&a1,&a2);
   cout<<"c_y: " <<endl;
   cout<<"a1: "<< a1 <<endl;
   cout<<"a2: "<< a2 <<endl;
   cout<<"" <<endl;



   cout<<"a1: "<< a1 <<endl;
   cout<<"a2: "<< a2 <<endl;
  //   func_swap_z(b1,b2);
  //   func_swap_z(a1,a2);
  //a是b的别名,则b也是a的别名吗?
  //这两个语句都可以运行出正确结果
   cout<<"c_z: " <<endl;
   cout<<"a1: "<< a1 <<endl;
   cout<<"a2: "<< a2 <<endl;

}

2.4 引用做函数返回值

  • 不要返回局部变量引用
  • 在这里插入图片描述

2.5 引用的本质(引用的本质在c++内部实现是一个指针常量.)

2.6 常量引用(const)

//引用使用的场景,通常用来修饰形参
void showValue(const int& v) {
    
      
    //const加入就不能修改形参
	//v += 10;
	cout << v << endl;
}

int main() {
    
    

	//int& ref = 10;  引用本身需要一个合法的内存空间,因此这行错误
	//加入const就可以了,编译器优化代码,int temp = 10; const int& ref = temp;
	const int& ref = 10;

	//ref = 100;  //加入const后不可以修改变量
	cout << ref << endl;

	//函数中利用常量引用防止误操作修改实参
	int a = 10;
	showValue(a);

	system("pause");

	return 0;
}

3 函数提高

3.1 函数默认参数

  • 1 . 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值
  • 2 . 如果函数声明有默认值,函数实现的时候就不能有默认参数
    参数默认值

3.2 函数占位参数

  • 调用的时候占位参数必须填补

3.3 函数重载

  • 同一个作用域下
  • 函数名称相同
  • 函数参数类型不同 或者 个数不同 或者 顺序不同
  • 函数的返回值不可以作为函数重载的条件
//函数重载注意事项
//1、引用作为重载条件

void func(int &a)
{
    
    
	cout << "func (int &a) 调用 " << endl;
}

void func(const int &a)
{
    
    
	cout << "func (const int &a) 调用 " << endl;
}


//2、函数重载碰到函数默认参数

void func2(int a, int b = 10)
{
    
    
	cout << "func2(int a, int b = 10) 调用" << endl;
}

void func2(int a)
{
    
    
	cout << "func2(int a) 调用" << endl;
}

int main() {
    
    
	
	int a = 10;
	func(a); //调用无const
	func(10);//调用有const


	//func2(10); //碰到默认参数产生歧义,需要避免

	system("pause");

	return 0;
}

4 类和对象(封装、继承、多态)

4.1 封装

  • 具有相同性质的对象,我们可以抽象称为
  • 属性一般设置私有,外部设置接口即可,在访问权限下设计接口
    1. 设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号。
#include <iostream>
using namespace std;

class Student
{
    
    
public:
     string name;
     string num;
     void setName(string myName){
    
    

        name= myName;
    }
     void setNum(string myNum){
    
    
       num=myNum;
    }

     void getName(){
    
    
       cout << "name:" << name <<endl;


    }
    void getNum(){
    
    

          cout<< "num:" << num << endl;
    }
};

int main() {
    
    

   // Student stu = new Student();
    Student stu ;
    stu.setName("John");
    stu.setNum("123");
    stu.getNum();
    stu.getName();

	system("pause");

	return 0;
}

  • 2 .设计立方体类(Cube),求出立方体的面积和体积,分别用全局函数和成员函数判断两个立方体是否相等。
//利用全局函数判断两个立方体是否相等//长宽高分别向邓
bool isSame(Cube &c1,Cube &c2)    //用引用的方式传递
{
    
    
	if (c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH())
	{
    
    
		return true;
	}
	return false;
}



//调用
bool ret=isSame(c1, c2);      //isSame是全局函数
	 
  • 3 .点和圆的关系设计一个圆形类(Circle),和一个点类(Point),计算点和圆的位置关系(内,外,上)。
#include<iostream>
using namespace std;

//点类
class Point
{
    
    
public:
	//设置x坐标
	void setX(int x)
	{
    
    
		m_X = x;
	}
	//获取x坐标
	int getX()
	{
    
    
		return m_X;
	}
	//设置y坐标
	void setY(int y)
	{
    
    
		m_Y = y;
	}
	//获取y坐标
	int getY()
	{
    
    
		return m_Y;
	}
private:
	int m_X;  //x坐标
	int m_Y;  //y坐标



};




//圆类
class Circle
{
    
    
public:
	//设置半径
	void setR(int r)
	{
    
    
		m_r = r;
	}
	//获取半径
	int getR()
	{
    
    
		return m_r;
	}
	//设置圆心
	void setCenter(Point center)
	{
    
    
		m_Center = center;
	}
	//获取圆心
	Point getCenter()
	{
    
    
		return m_Center;
	}
	//属性
private:
	int m_r; //半径
	Point m_Center; //圆心
};
//判断点和圆的关系
//void  isInCircle(Circle& c, Point& p)
void isInCirle(Circle &c,Point &p)
{
    
    
	//计算两点之间的距离平方
	int distance =
		(c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) + (c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
	//计算半径的平方
	int rDistance =
		c.getR() * c.getR();

	//判断关系
	if (distance = rDistance)
	{
    
    
		cout << "点在圆上" << endl;
	}
	else
	{
    
    
		if (distance > rDistance)
		{
    
    
			cout << "点在圆外" << endl;
		}
		else
		{
    
    
			cout << "点在圆内" << endl;
		}
	}
}


int main()
{
    
    
	//创建圆
	Circle c;
	c.setR(10);
	Point center;
	center.setX(10);
	center.setY(0);
	c.setCenter(center);
	//创建点
	Point p;
	p.setX(10);
	p.setY(10);

	//判断关系
	isInCirle(c, p);





	system("pause");
	return 0;
}

4.2 对象的初始化和清理

-构造函数(没有返回值,new? , 和JAVA有什么区别吗)

//1、构造函数分类
// 按照参数分类分为 有参和无参构造   无参又称为默认构造函数
// 按照类型分类分为 普通构造和拷贝构造

class Person {
    
    
public:
	//无参(默认)构造函数
	Person() {
    
    
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int a) {
    
    
		age = a;
		cout << "有参构造函数!" << endl;
	}
	//拷贝构造函数
	Person(const Person& p) {
    
    
        // 将传入的人身上的所有属性,拷贝到我身上
		age = p.age;
		cout << "拷贝构造函数!" << endl;
	}
	//析构函数
	~Person() {
    
    
		cout << "析构函数!" << endl;
	}
public:
	int age;
};

//2、构造函数的调用
//调用无参构造函数
void test01() {
    
    
	Person p; //调用无参构造函数
}

//调用有参的构造函数
void test02() {
    
    

	//2.1  括号法,常用
	Person p1(10);
	//注意1:调用无参构造函数不能加括号,如果加了编译器认为这是一个函数声明
	//Person p2();

	//2.2 显式法
	Person p2 = Person(10); 
	Person p3 = Person(p2);
	//Person(10)单独写就是匿名对象  当前行结束之后,马上析构

	//2.3 隐式转换法
	Person p4 = 10; // Person p4 = Person(10); 
	Person p5 = p4; // Person p5 = Person(p4); 

	//注意2:不能利用 拷贝构造函数 初始化匿名对象 编译器认为是对象声明
	//Person p5(p4);
}

int main() {
    
    

	test01();
	//test02();

	system("pause");

	return 0;
}

  • C++中拷贝构造函数调用时机通常有三种情况
    1 使用一个已经创建完毕的对象来初始化一个新对象
    2 值传递的方式给函数参数传值
    3 以值方式返回局部对象
    ??????
Person(const Person& p) {
    
    
		cout << "拷贝构造函数!" << endl;
		mAge = p.mAge;
	}

这个不明白

class Person {
    
    
public:
	Person() {
    
    
		cout << "无参构造函数!" << endl;
		mAge = 0;
	}
	Person(int age) {
    
    
		cout << "有参构造函数!" << endl;
		mAge = age;
	}
	Person(const Person& p) {
    
    
		cout << "拷贝构造函数!" << endl;
		mAge = p.mAge;
	}
	//析构函数在释放内存之前调用
	~Person() {
    
    
		cout << "析构函数!" << endl;
	}
public:
	int mAge;
};

//1. 使用一个已经创建完毕的对象来初始化一个新对象
void test01() {
    
    

	Person man(100); //p对象已经创建完毕
	Person newman(man); //调用拷贝构造函数
	Person newman2 = man; //拷贝构造

	//Person newman3;
	//newman3 = man; //不是调用拷贝构造函数,赋值操作
}

//2. 值传递的方式给函数参数传值
//相当于Person p1 = p;
void doWork(Person p1) {
    
    }
void test02() {
    
    
	Person p; //无参构造函数
	doWork(p);
}

//3. 以值方式返回局部对象
Person doWork2()
{
    
    
	Person p1;
	cout << (int *)&p1 << endl;
	return p1;
}

void test03()
{
    
    
	Person p = doWork2();
	cout << (int *)&p << endl;
}


int main() {
    
    

	//test01();
	//test02();
	test03();

	system("pause");

	return 0;
}

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

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

传统方式初始化
	//Person(int a, int b, int c) {
    
    
	//	m_A = a;
	//	m_B = b;
	//	m_C = c;
	//}

	//初始化列表方式初始化
	Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {
    
    }
	void PrintPerson() {
    
    
		cout << "mA:" << m_A << endl;
		cout << "mB:" << m_B << endl;
		cout << "mC:" << m_C << endl;
	}

静态

class Person
{
    
    
	
public:

	static int m_A; //静态成员变量

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

private:
	static int m_B; //静态成员变量也是有访问权限的
};
int Person::m_A = 10;
int Person::m_B = 10;

void test01()
{
    
    
	//静态成员变量两种访问方式

	//1、通过对象
	Person p1;
	p1.m_A = 100;
	cout << "p1.m_A = " << p1.m_A << endl;

	Person p2;
	p2.m_A = 200;
	cout << "p1.m_A = " << p1.m_A << endl; //共享同一份数据
	cout << "p2.m_A = " << p2.m_A << endl;

	//2、通过类名
	cout << "m_A = " << Person::m_A << endl;


	//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
}

int main() {
    
    

	test01();

	system("pause");

	return 0;
}

class Person
{
    
    

public:

	//静态成员函数特点:
	//1 程序共享一个函数
	//2 静态成员函数只能访问静态成员变量
	
	static void func()
	{
    
    
		cout << "func调用" << endl;
		m_A = 100;
		//m_B = 100; //错误,不可以访问非静态成员变量
	}

	static int m_A; //静态成员变量
	int m_B; // 
private:

	//静态成员函数也是有访问权限的
	static void func2()
	{
    
    
		cout << "func2调用" << endl;
	}
};
int Person::m_A = 10;


void test01()
{
    
    
	//静态成员变量两种访问方式

	//1、通过对象
	Person p1;
	p1.func();

	//2、通过类名
	Person::func();


	//Person::func2(); //私有权限访问不到
}

int main() {
    
    

	test01();

	system("pause");

	return 0;
}

4.3 C++对象模型和this指针

4.4 友元

4.5 运算符重载

4.6 继承

4.7 多态

5 文件操作

5.1文本文件

5.2 二进制文件

猜你喜欢

转载自blog.csdn.net/weixin_45783317/article/details/128623351