C++基础-内联函数inline,重载,extern “C“ 及封装

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方法访问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值