C++语言基础Day3-内联函数

一、预处理宏定义的缺陷

 预处理宏存在问题的关键是我们可能认为预处理器的行为和编译器的行为是一样的。当然也是由于宏函数调用和函数调用在外表看起来是一样的,因为也容易被混淆,但是其中也会存在一些微妙的问题出现。

问题案例1:

#include<iostream>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#define ADD(x,y) x + y 

void test()
{
	int ref = ADD(10,20) * 2;// 编译器翻译成 10 + 20 * 2
	cout << "ref = " << ref << endl;
}

int main()
{
	test();

	return EXIT_SUCCESS;
}

使用内联函数可以解决该问题

#include<iostream>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#define ADD(x,y) x + y 

// 在普通函数前面加上Inline是像编译器申请成为内联函数
inline int Add(int x, int y)
{
	return x + y;
}


void test()
{
	//int ref = ADD(10,20) * 2;// 编译器翻译成 10 + 20 * 2
	//cout << "ref = " << ref << endl;

	int ref2 = Add(10, 20) * 2;
	cout << "ref2 = " << ref2 << endl;
}

int main()
{
	test();

	return EXIT_SUCCESS;
}

问题案例2:

#define COMAPD(x,y) ((x) < (y)?(x):(y))

// 宏定义缺陷
void test02()
{
	int a = 1;
	int b = 3;

	// 编译器翻译成:(++a) < (b) ?(++a):(b)  
	cout << "comapd(x,y) = " << COMAPD(++a, b) << endl;// 输出3
}


int main()
{
	test02();

	return EXIT_SUCCESS;
}

使用内联函数可以解决该问题

inline int func(int x, int y)
{
	return x < y ? x : y;
}

// 宏定义缺陷
void test02()
{
	int a = 1;
	int b = 3;

	// 编译器翻译成:(++a) < (b) ?(++a):(b)  
	//cout << "comapd(x,y) = " << COMAPD(++a, b) << endl;// 输出3

	cout << "结果是:" << func(++a, b) << endl;
}

int main()
{
	test02();

	return EXIT_SUCCESS;
}

二、什么情况不会成为内联函数

  • 存在过多的条件判断语句
  • 函数体过大
  • 对函数进行取地址操作
  • 不能存在任何形式的循环语句

三、内联函数的好处

  • 有宏函数的效率,没有宏函数的缺点
  • 类的成员函数默认加上inline

四、编译器对内联函数进行何种处理

 对于任何类型的函数,编译器会将函数类型(包括函数名字,参数类型,返回值类型)放入到符号表中,同样的,当编译器看到内联函数,并且对内联函数体进行分析没有发现错误时,也会将内联函数放入到符号表中。

 当调用一个内联函数的时候,编译器首先确保传入的参数类型是正确匹配的,或者入伏哦类型不正确匹配,但是可以将其转换为正确类型,并且返回值在目标表达式匹配正确类型或者可以转换为目标类型,内联函数就会直接替换函数调用,这就消除了函数调用的开销。加入内联函数是成员函数,对象this指针也会被放入合适的位置。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,让我来回答你的问题。 对于这个问题,我可以提供如下代码实现: ``` #include<iostream> #include<string> using namespace std; class Date{ private: int year; int month; int day; public: Date(int y=0,int m=1,int d=1):year(y),month(m),day(d){}//构造函数 ~Date(){}//析构函数 int getYear(){return year;} void setYear(int y){year=y;} int getMonth(){return month;} void setMonth(int m){month=m;} int getDay(){return day;} void setDay(int d){day=d;} void show(){cout<<year<<"/"<<month<<"/"<<day<<endl;} }; class Book{ private: string name; double price; Date date; public: Book(string n,double p,int y=2022,int m=1,int d=1):name(n),price(p),date(Date(y,m,d)){}//构造函数 ~Book(){}//析构函数 void setBook(string n,double p,int y=2022,int m=1,int d=1){ name=n; price=p; date.setYear(y); date.setMonth(m); date.setDay(d); } void show() { cout<<"书名:"<<name<<endl; cout<<"价格:"<<price<<endl; cout<<"出版日期:"; date.show();//调用日期类的show函数输出出版日期 } int getYears() { int nowyear = 2022; //当前年份,根据实际情况自行更改 return nowyear - date.getYear(); } }; int main() { Book book("C++ Primer Plus",99.0,2021,1,1); book.show(); cout<<"出版年限:"<<book.getYears()<<endl; return 0; } ``` 解释一下代码的实现,首先我们定义了一个日期类 `Date`,其中包括了年份、月份和日期三个数据成员,同时提供了构造函数、析构函数、获取年份、设置年份等成员函数。注意到这里缺省参数的使用,以及内联函数 `show()` 的定义。 接下来我们定义了一个图书类 `Book`,它包括了书名、价格和出版日期三个数据成员。其中,出版日期用到了之前定义的日期类,因此我们在构造函数中调用日期类的构造函数来初始化日期,同时将书名和价格作为参数传入构造函数初始化。同样地,我们也提供构造函数、析构函数、设置图书信息和获取出版年限等成员函数。 在 `main` 函数中,我们创建了一个 `Book` 对象 `book`,并初始化书名、价格和出版日期,然后调用其成员函数 `show()` 输出图书信息和出版年限。 这就是一个简单的图书类的实现方法,如果你有其他的问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

少写代码少看论文多多睡觉

求打赏,求关注,求点赞

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

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

打赏作者

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

抵扣说明:

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

余额充值