01 设计圆类求周长
#include<iostream>
using namespace std;
const double pi = 3.14;
//1.设计一个类,求圆的周长
//周长公式 2*pi*r
class Circle //class代表声明一个类,后面紧跟的是类的名称
{
public://公共权限
//求圆的周长
//在类里面写函数,成员函数
double calculateZC()
{
return 2 * pi * m_R;
}
//设置半径的成员方法
void setR(int r)
{
m_R = r;
}
//半径 ,成员属性
int m_R;
};
int main()
{
//通过类来创建一个圆
Circle c1;//圆(对象)
//c1.m_R = 10;//给这个对象来进行半径的赋值
//通过成员函数,间接给圆设置半径
c1.setR(10);
//输出c1的周长
cout << "c1的周长为:" << c1.calculateZC() << endl;
system("pause");
return EXIT_SUCCESS;
}
02 设计学生类
#include<iostream>
#include<string>
using namespace std;
/*
2.设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号
*/
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);
cout << "st的姓名为:" << st.m_Name << "st的学号:" << st.m_Id << endl;
//通过成员函数来打印st的信息
st.showInfo();
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
总结:
类和对象的关系:
1.类是对象的抽象
2.对象是对类的实例
03 内联函数的引出-宏函数的缺陷
内联函数的缺陷:
缺陷1:要注意加括号
缺陷2:比较后自加
缺陷3:宏函数也没有作用域
#include<iostream>
using namespace std;
//缺陷1:要注意加括号
//定义一个加法
#define MyAdd(x,y) ((x)+(y))
void test01()
{
int ret = MyAdd(10, 20) * 20;//预期结果 600 ((10)+(20))*20 实际结果 410 10+20*20
cout << "ret=" << ret << endl;//所以加()
}
//缺陷2:比较后自加
#define MyCompare(a,b) ((a)<(b))?(a):(b) //返回最小值
inline void mycompare(int a, int b)
{
int ret = a < b ? a : b;
cout << "ret:" << ret << endl;
}
void test02()
{
int a = 10;
int b = 20;
int ret = MyCompare(a, b); //预期: ((a)<(b))?(a):(b) 返回10 没有问题
int ret = MyCompare(++a, b); //预期:11 ((++a)<(b))?(++a):(b) 结果:12
cout << "ret = " << ret << endl;
}
//缺陷3:宏函数也没有作用域
//内联函数注意事项:
inline void func(); // 内联函数声明
void func(); // 如果函数实现时候,没有加inline关键字,那么这个函数依然不算内联函数
int main()
{
system("pause");
return EXIT_SUCCESS;
}
内联函数注意事项:
1.类的成员函数 默认会在前面加上inline关键字
2.声明和实现分开写的时候都要加inline关键字
优点:
空间换时间,省去函数调用的开销时间
限制:
1.不能存在任何形式的循环语句
2.不能存在过多的条件判断语句
3.函数体不能过于庞大
4.不能对函数进行取址操作
内联函数解决宏缺陷问题
1.给编译器一个建议,加上关键字,编译器不一定安照内联处理
2.不加关键字,也许编译器还偷摸的给你加inline
3.成员函数,默认加上关键字
04 函数的默认参数以及占位参数
#include<iostream>
using namespace std;
//函数的默认参数,参数后面=...
//函数参数注意事项,如果有一个位置有了默认参数,那么从这个位置开始,从左往后都必须有默认参数
//传入参数,如果有参数,就用传入的参数,没有参数就用默认值
void func(int a, int b = 10, int c = 1)
{
cout << "a+b+c=" << a + b + c << endl;
}
void test01()
{
func(1, 2);//4
}
//函数占位参数
//如果有了占位参数,函数调用时候必须要提高这个参数,但是用不到参数
//占位参数,没有什么大用途,只有后面重载++符号才有一点点用
//占位参数,可以有默认值
//C语言中没有默认参数,C也没有占位参数
void func2(int a, int = 1)
{
}
//如果函数声明里面有了默认参数,那么函数实现时候必须没有
//函数声明和实现里,只有一个里面有默认参数,不要同时都出现默认参数
void myFunc(int a = 10, int b = 10);
void myFunc(int a,int b){}
int main()
{
system("pause");
return EXIT_SUCCESS;
}
05 函数重载的基本语法
#include<iostream>
using namespace std;
//函数重载
//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;
}
//返回值可以作为函数的重载条件吗?不可以
//int func(int a, double b)
//{
// cout << "有参数的func(int a, double b)" << endl;
//}
void test01()
{
func(1, 3.14);
}
//当函数重载碰到了默认参数时候,要只有避免二义性问题
void func2(int a, int b = 10)
{
}
void func2(int a)
{
}
void test02()
{
//func2(10);
}
//引用的重载版本
void fun3(int& a)//引用必须要引合法的内存空间
{
cout << "int &a" << endl;
}
void fun3(const int& a)//const也是可以作为重载的条件|int tmp = 10;const int &a=tmp
{
cout << "cosnt int &a" << endl;
}
void test03()
{
//int a = 10;
fun3(10);
}
int main()
{
system("pause");
return EXIT_SUCCESS;
}
06 extern C浅析
解决了C++中调用C语言代码
一个方法时
test.h:
#include<stdio.h>
void show();
test.c:
#include"test.h"
void show()
{
printf("hello world");
}
extern C浅析.cpp:
#include<iostream>
using namespace std;
//C++中想调用C语言方法
extern "C" void show();//show方法,按照C语言方式做链接
int main()
{
show();//在C++中,函数是可以发生重载的,编译器会把这个函数名称偷偷改变,_showv (v=void)
system("pause");
return EXIT_SUCCESS;
}
当方法过多时
test.h:
#ifdef __cplusplus//两个_下划线
extern "C" {
#endif //!__cplusplus
#include<stdio.h>
void show();
#ifdef __cplusplus//两个_下划线
}
#endif //!__cplusplus
test.c:
#include"test.h"
void show()
{
printf("hello world");
}
extern C浅析.cpp:
#include<iostream>
using namespace std;
#include "test.h"
//C++中想调用C语言方法
//extern "C" void show();//show方法,按照C语言方式做链接
int main()
{
show();//在C++中,函数是可以发生重载的,编译器会把这个函数名称偷偷改变,_showv (v=void)
system("pause");
return EXIT_SUCCESS;
}
07 C语言下的封装和C++语言的封装区别
C语言封装.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Person
{
char mName[64];
int mAge;
};
void PersonEat(struct Person *p)
{
printf("%s 在吃人饭\n",p->mName);
}
void test01()
{
struct Person p1;
strcpy(p1.mName, "老王");
PersonEat(&p1);
}
struct Dog
{
char mName[64];
int mAge;
};
void DogEat(struct Dog* dog)
{
printf("%s 在吃狗粮\n", dog->mName);
}
void test02()
{
struct Dog d;
strcpy(d.mName, "旺财");
DogEat(&d);
struct Person p1;
strcpy(p1.mName, "老王");
PersonEat(&p1);
}
//C语言封装,属性和行为分开处理了
int main()
{
test02();
system("pause");
return EXIT_SUCCESS;
}
C++语言下的封装:
#include <iostream>
#include <cstring>
using namespace std;
struct Person
{
char mName[64];
int mAge;
void PersonEat()
{
cout << mName << "吃人饭" << endl;
}
};
struct Dog
{
char mName[64];
int mAge;
void DogEat()
{
cout << mName << "吃狗粮" << endl;
}
};
// C++中的封装 严格类型转换检测 让属性和行为绑定在一起
// 属性和行为作为一个整体来表示生活中的事物
// 控制权限 pubilc 公有权限 protected 保护权限 privete 私有权限
void test01()
{
Person p1;
strcpy(p1.mName,"老王");
p1.PersonEat();
}
// struct 和 class 是一个意思,唯一的不同是默认权限
// struct 是 public,但是 class 是 private
// 所谓的私有权限 就是私有成员(属性、函数) 在类的内部可以访问,类外部不可以访问
// 公有权限 在类的内部和外部都可以访问
class Animal
{
private:
void eat()
{
mAge = 100;
}
int mAge;
public:
int mHeight;
protected: //保护权限,类内部可以访问,外部不可以访问,当前类的子类可以访问
int mWeigt;
};
void test02()
{
Animal an;
// an.eat();
// an.mAge; // 私有不可以访问
an.mHeight = 100; // 公有权限可以在类的外部访问
}
int main()
{
test01();
return 0;
}
建议将所有成员属性设置为私有,自己提供公共的对外接口来进行set和get方法访问