C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置。
语法:返回值类型 函数名 (数据类型){}//数据类型是占位参数
//目前阶段的展位参数我们还用不到,后面课程会用到。
//展位参数还有默认参数,void func(int a,int=10)
void func(int a ,int)
{
cout<<"hi"<<endl;
}
int main(){
func(10,10);//展位参数必须填报
system("pause")
}
3.3 函数重载
3.3.1 函数重载概述
在C++中函数名是可以相同的,提高复用性
函数重载满足的条件。1.同一个作用域下,2.函数名相同 3.函数参数类型不同或者个数不同或者顺序不同
注意:函数的返回值是不可以作为重载的条件的。
//函数重载的满足条件
//1同一个作用域下
void func()
{
cout<<"func的调用"<<endl;
}
void func(int a)
{
cout<<"func的调用"<<endl;
}
void func(double a)
{
cout<<"func的调用"<<endl;
}
void func(int a,double b)
{
cout<<"func的调用"<<endl;
}
void func(double a,int b)
{
cout<<"func的调用"<<endl;
}
int func(int a,double b)//wrong 函数的返回值不可以作为函数重载的条件,返回值类型不同不可以
{
cout<<"func的调用"<<endl;
}
int main()
{
func()
}
3.3.2 函数重载的注意事项
引用作为重载条件。
void func(int &a)//int &a = 10;不合法,引用必须在一个合法的内存空间要么在栈上要么在堆区
{
cout<<"func(int &a)调用"<<endl;
}
void func(const int &a)//这个只能读不能写。const int &a = 10;合法
{
cout<<"func(int &a)调用"<<endl;
}
int main()
{
//int a = 10;
//func(a);
//sytem("pause")调用第一个函数的
func(10)//调用下面的函数
}
函数重载碰到函数默认参数
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()
{
func(2)//当函数重载中出现了默认值,又能调用上面又能调用下面,出现了二义性。写函数重载不要写上默认参数
}
4 类和对象
面向对象的三大特性:封装继承多态
万物皆对象。对象有其属性和行为。对象上有其属性和行为。
具有相同性质的对象,我们可以抽象为类,人类。
4.1 封装
4.1.1 封装的意义
把属性和行为作为一个整体
将属性和行为加以权限控制
//class代表设计一个类,类后面紧跟着是类的名称
class circle
{
//访问权限
//公共权限
public:
//属性
//半径
int m_r;
//行为
//获取圆的周长
double calculateZC()
{
return 2*PI*m_r;
}
};
int main()
{
//通过圆类创建一个具体的对象圆
//实例化(通过一个类创建一个对象)
circle c1;
//给圆对象的属性进行赋值
c1.m_r = 10;
//2*PI*10 = 62.8
cout<<"圆的周长为"<<c1.calculateZC()<<endl;
}
//设计一个学生类,属性有姓名学号
class student
{
public://公共
//属性
string m_name;
int m_id;
//行为
//显示姓名和学号
void showStudent()
{
cout<<"姓名:"<<m_name<<"学号:"<<m_id<<endl;
}
};
int main()
{
//创建一个具体学生 实例化对象
student s1;
//给s1对象,进行属性赋值操作
s1.m_name = "赵捷";
s1.m_id = 1;
//显示学生信息
s1.showStudent();
student s2;
//给s1对象,进行属性赋值操作
s2.m_name = "赵er捷";
s2.m_id = 2;
//显示学生信息
s2.showStudent();
system("pause");
return 0;
}
class student
{
public:
//类中的属性和行为统称为成员
//属性 成员属性 成员变量,几个不同的名字
//行为 成员函数 成员方法
string m_name;
int m_id;
void showStudent()
{
cout<<"姓名:"<<m_name<<"学号:"<<m_id<<endl;
}
//给学号赋值
void setid(string id)
{
m_id = id;
}
void setName(string name)
{
m_Name = name;
}
};
int main()
{
student s1;//通过行为对函数进行赋值操作
s1.setname("zhangsan");
s1.m_id = 1;
s1.showstudent();
s1.setid(1);
}
封装意义二:
类在设计时,可以把属性和行为放在不同的权限下,加以控制。
访问权限有:
1.public 公共权限
2.protected 保护权限
3.private 私有权限
//访问权限
//公共权限public 成员类内可以访问 类外可以访问
//保护权限protected 类内可以访问 类外不可以访问 儿子也可以访问父亲中的保护内容
//私有权限private 类内可以访问 类外不可以访问 儿子不可以访问父亲的私有内容
class person
{
public:
string m_name;
protected:
string m_car;
private:
int m_password;
public://类内是可以访问属性的
void func()
{
m_name="za";
m_car ="tuolaji";
m_password = 123456;
}
}
int main()
{
person p1;
p1.m_name = "lisi";
p1.m_car = "penchi"//错误,保护权限内容,在类外访问不到
p1.m_password = 123;//错误,私有权限内容,在类外访问不到
}
4.1.2 struct 和 class的区别
默认的访问权限不同
struct默认权限是公共,class默认的是私有
class C1
{
int m_a;//默认私有权限
};
struct C2
{
int m_b;//默认权限是公共
};
int main()
{
C1 c1;
c1.m_a = 100;//错误,私有成员,类外不可以访问
C2 c2;
c2.m_b = 100;//正确
}
4.1.3 成员属性设置为私有
优点1,可以自己控制读写权限
优点2,对于写权限,可以检测数据的有效性
class Person
{
public:
//写姓名
void setName(string name)
{
m_Name = name;
}
//读姓名
//姓名 可读可写
string getName()
{
return m_Name;
}
//年龄 只读
int getAge()
{
m_age = 0;//初始化为0岁
return m_age;
}
//获取年龄,可读可写。写的范围0-150.第二个好处
void setAge(int age)
{
if (age < 0||age>150)
{
cout<<“你这个老妖精”<<endl;
return;
}
m_Age = age;
}
//情人 只写
void setlover(string lover)
{
return lover;
}
private:
//姓名 可读可写
string m_name;
//年龄 只读
int m_age;
//情人 只写
string m_lover;
};
int main()
{
Person p;
p.setName("张三")
cout << "姓名"<<p.getName()<<endl;
//p.m_Age = 18;错误不可写,不可以
//p.setAge(18);错误
cout <<" 年龄"<<p.getAge()<<endl;//正确可读
p.setlover("苍劲")//正确
cout << "情人为"<<p.m_Lover<<endl;//错误外面访问不到,不可读
system("pause")
return 0;
}
案例分析
设计立方体,求出立方体的面积和体积,
分别用全局函数和成员函数判断两个立方体是否相等。
//立方体设计
class Cude
{
public:
//设置长获取长,宽 高
void setL(int l)
{
m_L = 1;
}
int getL()
{
return m_L;
}
void setW(int w)
{
m_W = 1;
}
int getW()
{
return m_W;
}
void setH(int h)
{
m_H = 1;
}
int getH()
{
return m_H;
}
//获取立方体的面积
int calculateS()
{
return 2*(m_L*m_W+m_W*m_H+m_H*m_L);
}
int calculateV()
{
return m_L*m_W*m_H;
}
//利用成员函数判断两个立方体是否相等
bool isSameByClass(Cube &c)
{
if (m_L==c.getL&&m_W==c.getW&&m_H==c.getH)
{
return true;
}
return false;
}
private:
int m_L;
int m_W;
int m_H;
//利用全局函数判断两个立方体是否相等
bool isSame(Cube &c1,Cube &c2)
{
if (c1.getL==c2.getL&&c1.getW==c2.getW&&c1.getH==c2.getH)
{
return true;
}
return false;
}
int main()
{
//创建立方体对象
Cube c1;
c1.setL(10);
c1.setW(10);
c1.setH(10);
cout<<"c1的面积为"<<c1.calculateS()<<endl;
cout<<"c1的体积为"<<c1.calculateV()<<endl;
//创建第二个立方体
Cube c2;
c2.setL(10);
c2.setW(10);
c2.setH(10);
//利用全局函数判断
bool ret = isSame(c1,c2)
if (ret)
{
cout<<"相等"<<endl;
}
else
{
cout<<"buxiangdeng"<<endl;
}
//利用成员函数判断
ret = c1.isSameByClass(c2);
if (ret)
{
cout<<"相等"<<endl;
}
else
{
cout<<"buxiangdeng"<<endl;
}
}
案例2 点和圆的关系
//点类
//圆类
在类中可以让另一个类作为本来类的成员
把一个类拆到另外一个文件中
头文件中创建point.h
#pragma once
#include <iostream>
using namespace std;
class Point
{
public:
//留住函数的声明和变量的声明就可以了
void setX(int x);
int getX();
void setX(int y);
int getY();
}
源文件中创建point.cpp
#include "point.h"
void Point::setX(int x)
{
m_X=x;
}
int Point::setX(int x)
{
return m_X;
}
void Point::setY(int y)
{
return m_Y=y;
}
int Point::setY(int y)
{
return m_Y=y;
}
在主文件中,包含一下头文件就好了
#include "circle.h"
#include"Point.h"