day2-C++学习

"本文介绍了C++中的类和对象,包括如何设计计算圆周长的Circle类和展示学生信息的Student类。接着讲解了内联函数的概念及其注意事项,以及函数的默认参数和占位参数的使用。此外,还探讨了函数重载的基本原则,并分析了extern"C"在C++中调用C语言函数的作用。最后,对比了C语言和C++在封装方面的差异,强调了C++中严格的数据访问权限控制和类型检查。"
摘要由CSDN通过智能技术生成

1.习题解析 设计类 抽象类

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

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
const double pi = 3.14;

// 周长公式  2 * pi * r
class Circle //class代表声明一个类 后面紧跟的是类的名称
{
public: //公共权限
//求圆的周长
	//在类里面写函数  成员函数
	double calculateZC()
	{
		return 2 * pi * m_R;
	}

	//设置半径的成员方法
	//成员函数 可以修改成员属性
	void setR(int r)
	{
		m_R = r;
	}

	//半径  成员属性
	int m_R;

};

void test1()
{
	//通过类 来创建一个圆 
	Circle c1; //圆 (对象)
	//c1.m_R = 10; //给这个对象来进行半径的赋值
	//通过成员函数 间接给圆设置半径
	c1.setR(10);

	//输出c1的周长

	cout << "c1的周长为: " << c1.calculateZC() << endl;
}
int main(){
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

题目:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号

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

class Student
{
public: //公共权限

	//设置姓名
	void setName(string name)
	{
		m_Name = name;
	}
	//设置学号
	void setId(int id)
	{
		m_Id = id;
	}

	//打印信息
	void showInfo()
	{
		cout << "姓名:" << m_Name << " 学号: " << m_Id << endl;
	}

	string m_Name; //姓名
	int m_Id; //学号

};

void test01()
{
	//创建一个学生 实例化 --  通过类来创建对象的过程
	Student st;
	st.setName("张三");
	st.setId(1);

	//通过st的属性打印了 st信息
	cout << "st的姓名为: " << st.m_Name << " st的学号:" << st.m_Id << endl;
	

	//通过成员函数 来打印st的信息
	st.showInfo();
}

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

2.内联函数的引出

内联函数是为了解决宏缺陷

//定义一个加法
#define Myadd(x,y) x + y

void test1()
{
	int ret = Myadd(10, 20)*20;//预期结果600 实际结果为410

	cout << "ret = " << ret << endl;
}

内联函数的注意事项:
1.类内部的成员函数 默认前面会加inline关键字
2.函数声明时加了inline关键字,但是在实现时没有加inline关键字,那这个函数依然不算内联函数
3.是给编译器一个建议,加上关键字,编译器不一定按照内联处理,不加关键字,也许编译器还偷摸的给你加inline

3.函数的默认参数以及占位参数

C语言中没有默认参数,C也没有占位参数

C++语言中默认参数的注意事项

//函数的默认参数 参数后面=内容
//函数参数注意事项 如果有一个位置有了默认参数,那么从这个位置开始,从左往右都必须有默认参数
//传入参数,如果有参数,就用传入的参数,没有参数就用默认值
//如果函数声明里面有了默认参数,那么函数实现时候必须没有
//函数声明和实现里 只能有一个有默认参数,不要同时都出现默认参数
void myfunc(int a = 10, int b = 20);
void myfunc(int a , int b) {};
void func(int a, int b = 10, int c = 10)
{
	cout << "a + b + c = " << a + b + c<< endl;
}

C++语言中占位参数的注意事项

//函数 占位参数
//如果有了占位参数,函数调用时候必须要提供这个参数
//占位参数 没有什么大用途, 只有后面重载 ++符号才有一点点用
//占位参数 可以有默认值
void func2(int a, int = 1)
{

}
void test2()
{
	func2(10);
}

4.函数重载的基本使用

函数重载就是函数名相同
函数重载的注意事项

//函数重载
//C++中 函数名称可以重复
//必须在同一个作用域中,函数名称相同
//函数的参数 个数不同 或者 类型不同 或者 顺序不同
void func()
{
	cout << "无参数的func" << endl;
}

void func(int a)
{
	cout << "有参数的func(int a)" << endl;
}

void func(double a)
{
	cout << "有参数的func(double a)" << endl;
}

void func(double a, int b)
{
	cout << "有参数的func(double a, int b)" << endl;
}

void func(int a, double b)
{
	cout << "有参数的func(int a, double b)" << endl;
}

//返回值可以作为函数重载的条件吗??? 不可以
//当函数重载遇到默认参数时,要注意避免二义性问题
void func2(int a, int b = 10)
{

}
void func2(int a)
{

}
void test2()
{
	func2(10);//无法确定所赋的值是给哪个函数的变量a
}
//引用的重载版本
void func3(int& a)//引用必须要引用合法的内存空间
{
	cout << "int &a" << endl;
}
void func3(const int& a)//const也是可以作为重载的条件  可以看做int temp = 10,const int& a = temp
{
	cout << "const int &a"<< endl;
}
void test3()
{
	int a = 10;
}

5.extern C浅析

解决的问题是在C++中调用C语言的函数

extern "C" void show();//show方法按照C语言方式做连接

多个函数调用时用到的方法

#pragma once   //防止头文件重复编译
#ifdef __cplusplus  //两个下划线
extern "C" {
#endif // !__cplusplus


#include <stdio.h>

	void show();


#ifdef __cplusplus  //两个下划线
}
#endif // !__cplusplus  //两个下划线

6.C++和C下的封装

C语言封装 属性和行为分开处理了,类型检测不够

struct Person
{
	char name[64];
	int age;
};

void Personeat(struct Person* p)
{
	printf("%s 在吃饭 \n",p->name);
}

void test()
{
	struct Person p1;
	strcpy(p1.name, "张三");

	Personeat(&p1);
}

struct Dog
{
	char name[64];
	int age;
};

void Dogeat(struct Dog* d)
{
	printf("%s 在吃狗粮 \n", d->name);
}

void test2()
{
	struct Dog d1;
	strcpy(d1.name, "旺财");

	Dogeat(&d1);

	struct Person p1;
	strcpy(p1.name, "老王");

	Dogeat(&p1);//调用的函数不属于Person,但是能够执行
}

C++中的封装 严格类型转换检测, 让属性和行为绑定到一起

struct Person
{
	char name[64];
	int age;

	void Personeat()
	{
		cout << name << "吃饭" << endl;
	}
};

struct Dog
{
	char name[64];
	int age;

	void Dogeat()
	{
		cout << name << "吃狗粮" << endl;
	}
};

//C++中的封装 严格类型转换检测, 让属性和行为绑定到一起
//属性和行为作为一个整体来表示生活中的事物
void test()
{
	Person p1;
	strcpy(p1.name, "老王");
	p1.Personeat();
	p1.Dogeat();//无法执行不属于Person的行为
}

控制权限 public公有权限 protected保护权限 private私有权限

//struct和class是一个意思,唯一不同的是 默认权限,struct是public  但是class是private
class Animal
{
private:
	//如果不声明权限,默认的权限是private
	void eat() { age = 15; };
	int age;

public:

	int height;

protected://保护权限 类的内部可以访问,(当前类的子类可以访问),类外部不可以访问

	int weight;

	void setweight()
	{
		weight = 140;
	}
};

//所谓的私有权限 就是私有成员(属性、函数) 在类的内部可以访问,类的外部不可以访问
//公共权限,在类的内部和外部都可以访问
void test2()
{ 
	Animal an;
	//an.eat();
	//an.age;//私有不可以访问
	an.height = 140;//公共权限在类的外部可以访问

	//an.weight = 140;//保护权限在类外不可访问
}

//public 类内 类外都可访问
//protected  类内可以访问 类外 不可以访问(子类可以访问)
//private 类内可以访问 类外 不可以访问 (子类也不可以访问)

建议将所有成员属性设置为私有,自己提供公共的对外接口来进行 set或者get方法访问

class Person
{
public:
	void setage(int age1)//设置年龄 写权限
	{
		if (age1 < 0 || age1 > 100)
		{
			cout << "你这个老妖精" << endl;
			return;
		}
		age = age1;
	}
	int getage()//获取年龄 读权限
	{
		return age;
	}

	string getname()//读姓名权限
	{
		return name;
	}
	void setname(string name1)//写姓名权限
	{
		name = name1;
	}

	void setlover(string lover1)//只写的情人权限
	{
		lover = lover1;
	}

private://类外不可访问 类内可访问
	string name;//私有权限 读写权限
	int age = 180;//私有权限 读写权限
	string lover;//私有权限 只写
};
void test()
{
	Person p1;
	//p1.age = 18;
	p1.setname("老王");

	cout << "p1的姓名:" << p1.getname() << endl;

	p1.setage(120);
	cout << "p1的年龄:" << p1.getage() << endl;

	p1.setlover("美");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值