c++笔记---02

1 设计一个类,求圆的周长
1.1 class + 类名 { 成员变量 成员函数 }
1.2 公共权限 public
1.3 设计成员属性
1.3.1 半径 int m_R
1.4 设计成员函数
1.4.1 获取圆周长 int calculateZC(){}
1.4.2 获取圆半径 int getR()
1.4.3 设置圆半径 void setR()
1.5 通过类创建对象过程 称为 实例化对象

#define CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

const double PI = 3.14;

//设计一个类,求圆的周长

//class + 类名
class Circle
{
public:	//公共权限
	//求圆的周长
	double calculateZC()
	{
		return 2 * PI * m_R;
	}

	//设置半径
	void setR(int r)
	{
		m_R = r;
	}

	//获取半径

	int getR()
	{
		return m_R;
	}

	//半径
	int m_R;
};

void test01()
{
	Circle c1;	//通过类 创建一个对象 实际化比例

	//给c1半径赋值
	//c1.m_R = 10;
	c1.setR(10);

	//求c1圆周长
	cout << "圆的周长为: " << c1.calculateZC() << endl;
	cout << "圆的半径为: " << c1.getR() << endl;
}



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

class Student
{
public:

	//设置姓名
	void setName(string name)
	{
		m_Name = name;
	}

	//设置学号
	void setId(int id)
	{
		m_Id = id;
	}

	//显示学生信息
	void showStudent()
	{
		cout << "姓名: " << m_Name << " 学号:" << m_Id << endl;
	}

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

};

void test02()
{
	Student s1;
	s1.m_Name = "张三";
	s1.m_Id = 123;
	cout << "姓名: " << s1.m_Name << " 学号:" << s1.m_Id << endl;

	Student s2;
	s2.setName("李四");
	s2.setId(1001);
	s2.showStudent();

}
int main()
{
	test01();
	test02();
	return EXIT_SUCCESS;
}

2 内联函数
2.1 内联函数引出—宏缺陷
2.1.1 宏缺陷:
2.1.1.1 必须要加括号保证运算完整
2.1.1.2 即使加括号,有些运算依然与预期结果不符
2.1.2 普通函数不会出现缺陷
2.2 C++提供 内联函数代替宏函数
2.3 关键字 inline
2.4 在函数声明和实现中同时加入关键字 inline 才称为内联
2.5 在成员函数前 都隐式加了关键字inline
2.6 有些特殊情况下 ,写了关键字inline也不会按照内联方式处理
2.6.1 出现循环
2.6.2 出现判断
2.6.3 函数体过于庞大
2.6.4 对函数进行取地址
2.7 总结: 内联函数只是给编译器一个建议,但是编译器不一定接受这个建议,好的编译器会自己给短小的函数前加上关键字inline
内联函数.cpp

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

//宏缺陷1:必须要加括号保证运算完整
#define MYADD(x,y) ((x) + (y))
void test01()
{
	int a = 10;
	int b = 20;
	int ret = MYADD(a, b) * 20;
	cout << ret << endl;

}

//宏缺陷2:即使加了括号,有些运算依然与预期不符
#define MYCOMPARE(a,b) (((a) < (b)) ? (a) : (b))

//普通函数不会出现与预期结果不符的问题
void myCompare(int a, int b)
{
	int ret = a < b ? a : b;
	cout << "ret = " << ret << endl;
}

void test02()
{
	int a = 10;
	int b = 20;

	myCompare(++a,b);
	//int ret = MYCOMPARE(++a, b);	//预期是11 结果是12  (((++a) < (b)) ? (++a) : (b))
	//cout << "ret = " << ret << endl;

}

//内联函数
//函数的声明和实现必须同时加关键字 inline 才算内联函数
//内联函数 好处 :解决宏缺陷,本身是一个函数,带来宏优势,以空间换空间,在适当的时候展开
inline void func();
inline void func() {};
//类内部的成员函数 在函数前都隐式加了关键字inline
//c++内部编译会有一些限制,以下情况编译器可能考虑不会将函数进行内联编译:
	/*不能存在任何形式的循环语句
	 *不能存在过多的条件判断语句 
	 *函数体不能过于庞大
	 * 不能对函数进行取值操作
	*/

//内联仅仅是给编译器一个建议,编译器不一定会接受这种建议
//如果你没有将函数声明为内联函数,那么编译器也可能将此函数做内联编译
//一个好的编译器将会内联小的、简单的函数

int main()
{
	//test01();
	test02();
	return EXIT_SUCCESS;
}

3 函数的默认参数和占位参数
3.1 默认参数
3.1.1 可以给函数的形参添加默认值
3.1.2 语法 形参 类型 变量 = 默认值
3.1.3 int func(int a, int b = 10 , int c = 10)
3.1.4 注意事项 ,如果有一个位置有了默认参数,那么从这个位置起,从左到右都必须有默认值
3.1.5 函数的声明和实现 只能有一个 提供默认参数,不可以同时加默认参数
3.2 占位参数
3.2.1 只写一个类型进行占位,调用时候必须要传入占位值
3.2.2 void func2(int a , int = 1)
3.2.3 占位参数也可以有默认值

函数的默认参数和占位参数.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//默认参数 语法 形参 类型 变量 = 默认值
//注意事项,如果有一个位置有了默认参数,那么从这个位置起,从左到右都必须有默认值
int func(int a, int b = 10,int c=10)
{
	return a + b + c;
}

void test01()
{
	cout << func(20,10) << endl;
}

//函数的声明和实现 只能与一个 提供默认参数,不可同时加默认参数
void myFunc(int a, int b);
void myFunc(int a = 20, int b = 20) {};

//占位参数 只写一个类型进行占位,调用时候必须要传入占位值
//占位参数 用途?
void func2(int a, int = 1)
{

}

void test02()
{
	func2(10);
}


int main()
{
	test01();
	return EXIT_SUCCESS;
}

4 函数重载
4.1 满足条件
4.1.1 同一个作用域下
4.1.2 函数名称相同
4.1.3 函数参数个数、类型、顺序不同
4.2 函数的返回值 不可以作为重载条件
4.3 注意事项
4.3.1 加const和不加const的引用可以作为重载条件
4.3.2 函数重载碰到默认参数 注意避免二义性出现

函数重载.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//函数重载条件
//1、在同一作用域
//2、函数名称相同
//3、参数个数、类型、顺序不同

/*
class Person
{
public:
	void func()	//成员函数 而不是全局函数
	{
	}
};
*/

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(int a, double b)
{
	cout << "func(int a,double b)调用" << endl;
}

void func(double a, int b)
{
	cout << "func(double a,int b)调用" << endl;
}


//返回值不可以作函数重载的条件
void test01()
{
	func(1,3.14);
}

//函数重载中 引用两个版本
/*避免二重定义出现
void myFunc(a)
{
	cout << "myFunc(int a)调用" << endl;
}
*/

void myFunc(int& a)		//int &a = 10;
{
	cout << "myFunc(int &a)调用" << endl;
}

void myFunc(const int& a)	//const int &a = 10;
{
	cout << "myFunc(const int &a)调用" << endl;
}
void test02()
{
	int a = 10;
	myFunc(100);	//myFunc(const int& a)调用		
	myFunc(a);		//myFunc(int& a)调用
}

//函数重载碰到默认参数,注意避免二义性出现
void func2(int a, int b = 10)
{

}

void func2(int a)
{

}
void test03()
{
	func2(10,10);
}
int main()
{
	//test01();
	test02();
	return EXIT_SUCCESS;
}

5 extern C 浅析
5.1 用途:在C++中调用C语言文件
5.2 C++中有函数重载,会对函数名称做修饰,导致调用C语言的函数链接失败
5.3 利用extern C可以解决问题
5.3.1 方法1:
5.3.1.1 在C++代码中加入
5.3.1.2 告诉编译器 show函数用C语言方式 做链接
5.3.1.3 //extern “C” void show();
5.3.2 方法2:
5.3.2.1 在C语言的头文件中加入6行代码

#ifdef __cplusplus  // 两个下划线  __  c plus plus
extern "C" {
#endif
				
#ifdef __cplusplus  // 两个下划线  __  c plus plus
}
#endif	

头文件test.h

#ifdef __cplusplus  // 两个下划线  __  c plus plus
extern "C" {
#endif

#include <stdio.h>

	void show();


#ifdef __cplusplus
}
#endif


test.c

#include "test.h"

void show()
{
	printf("hello world\n");
}

externC浅析.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include "test.h"


//告诉编译器  show函数用C语言方式 做链接
//extern "C" void show();




void test01()
{
	show();//_Z4showv;在C++中有函数重载会修饰函数名,但是show是c语言文件,因此链接失败
}



int main() {
	test01();


	system("pause");
	return EXIT_SUCCESS;
}

6 封装
6.1 C语言的封装
6.1.1 缺陷 将属性和行为分离
6.2 C++语言的封装
6.2.1 将属性和行为作为一个整体,来表现生活中的事物
6.2.2 将属性和行为 加以权限控制
6.3 访问权限
6.3.1 公共权限 public 类内 类外 都可以访问
6.3.2 私有权限 private 类内可以访问 类外不可以访问
6.3.3 保护权限 protected类内可以访问 类外不可以访问
6.4 class 默认权限 私有权限 而 struct默认权限是 公共权限

c的封装

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

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

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

void test01()
{
	struct Person p;
	strcpy(p.name, "张三");
	p.age = 10;

	PersonEat(&p);
}


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

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

void test02()
{
	struct Dog d;
	strcpy(d.name, "旺财");
	d.age = 100;

	DogEat(&d);


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

	DogEat(&p);

}



int main() {
	//	test01();
	test02();

	system("pause");
	return EXIT_SUCCESS;
}

c++的封装

#define _CRT_SECURE_NOWARINGS
#include<iostream>
using namespace std;

struct Person
{
	//公共权限
public:
	char name[64];
	int age;

	void PersonEat()
	{
		printf("%s在吃饭",name);
	}
};

struct Dog
{
	//公共权限
public:
	char name[64];
	int age;

	void DogEat()
	{
		printf("%s在吃狗粮",name);
	}
};

//C++封装 理念:将属性和行为作为一个整体,来表现生活中的事务

//第二次理念:将属性和行为 加以权限控制

void test01()
{
	struct Person p;
	strcpy(p.name,"老王");

	p.PersonEat();

	//p.DogEat();
}

//struct和class区别
//class 默认权限 私有权限 而struct默认权限是公共权限
//访问权限
//public 公共权限		成员 类内 类外 都可访问
//private 私有权限		成员 类内 可以访问	类外 不可以访问 儿子不可以访问父亲的private权限内容
//protected 保护权限	成员 类内 可以访问	类外 不可以访问 儿子可以访问父亲的protected权限内容

class Person2
{
public:
	string m_Name;	//公共权限
protected:
	string m_Car;	//保护权限
private:
	int m_pwd;	//私有权限

public:
	void func()
	{
		m_Name = "张三";
		m_Car = "法拉利";
		m_pwd = 123456;
	}

};

void test02()
{
	Person2 p;
	p.m_Name = "李四";	//公共权限 类外可以访问
	//p.m_Car = "法拉利";	//保护权限 类外访问不到
	//p.m_pwd = 123;		//私有权限 类外不可以访问
}
int main()
{
	//test01();
	test02();

	return EXIT_SUCCESS;
}

7 尽量将成员属性设置为私有
7.1 自己可以控制读写权限
7.2 可以对设置内容 加有效性验证

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include <string>
class Person
{
public:
	//设置姓名
	void setName(string name)
	{
		m_Name = name;
	}
	//获取姓名
	string getName()
	{
		return m_Name;
	}

	//获取年龄
	int getAge()
	{
		return m_Age;
	}

	//设置年龄
	void setAge(int age)
	{
		if (age < 0 || age > 150)
		{
			cout << "你这个老妖精" << endl;
			return;
		}
		m_Age = age;
	}

	//设置爱人
	void setLover(string lover)
	{
		m_Lover = lover;
	}

private:
	string m_Name;  //姓名  可读可写
	int m_Age = 18;      //年龄  可读 可写(0 ~ 150之间)
	string m_Lover; //爱人  只写
};

void test01()
{
	Person p;
	//可以将char * 隐式类型转换为 string
	p.setName("张三");
	cout << "姓名: " << p.getName() << endl;

	//获取年龄
	p.setAge(100);
	cout << "年龄: " << p.getAge() << endl;

	//设置爱人
	p.setLover("光头强");

	//cout << "张三爱人是:"<< p.m_Lover <<endl; //爱人是只写权限  外部访问不到

}

//将成员属性都设置为私有好处:自己可以控制读写权限
//可以对设置内容 加有效性验证
int main() {
	test01();


	system("pause");
	return EXIT_SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sunshime.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值