C++入门篇-----inline,auto,nullptr

内联函数

内联函数的概念:以关键字inline修饰的函数称为内联函数。C++编译器会在函数调用的地方直接展开,而不是去调用
函数,这样避免了函数栈帧的创建,可以提高效率

看看没有inline修饰的函数,他是去调用函数(call是调用的意思),建立函数栈帧

int Count()
{
	int a = 10;
	return a;
}

int main()
{
    Count();
	return 0;
}

在这里插入图片描述
加上inline修饰的函数还会去调用吗? 下面两种方法都不会去调用
1,加上inline,改为release版本下运行,打完断点,转到反汇编,你会发现函数都点进不去(这路就不试了)
2,加上inline,在Debug版本下设置一下,因为编译器的Debug版本下,默认是不会优化的,设置方式如图
点开该项目的属性
在这里插入图片描述

inline int Count()
{
	int a = 10;
	return a;
}

int main()
{
    Count();
	return 0;
}

在这里插入图片描述

inline函数的特性
1,以空间换时间,避免函数栈帧的创建,但是函数中有循环或者递归就不适合用内联,因为展开的话会超级长
2,对编译器仅仅是个建议,听不听还要编译器的心情 ,哈哈
3,inline修饰函数在多文件中,声明和定义是一定不能分开的,因为inline函数会被展开,从而找不到函数的地址

提一下宏的优点和缺点
1,增强代码的复用性
2,提高性能

缺点:
1,不方便调试
2,没有类型检查
3,代码可读性差,可维护性差,易出错

C++有什么可以替代宏的吗?
1,const 修饰的常量
2,inline修饰的函数

auto

C++中的auto不是用来定义局部变量,而是来进行推导变量的类型的

1,auto定义的变量必须初始化
2,auto可以一行定义多个变量,但是每个常量必须相同

int main()
{
	int a = 10;
	auto b = a;   //这里推导的b是int  
	auto c = "a"; //c是char
	
	auto d = &a;   //者两个用法是完全一样的,都是定义了指针
	auto* e = &a; 
	
	auto& f = a;   //定义引用必须加上&

    auto x = 10, y =20;
    auto x = 2.2, y = 10;  //报错

	return 0;
}

在这里插入图片描述
auto不适合的场景是
1,不适合做函数的参数,(可以作为返回类型,VS2019不报错)
2,不适合用来定义数组

范围for的用法

int main()
{
	int a[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };

	//分号分割,左边是把数组中的元素赋值给e,右边是数组名
	//这里的e的类型也可以写出int,但是我们习惯用auto
	for (auto e : a)
	{
		cout << e << " ";
	}
	return 0;
}

如果要改变数组中的元素要怎么办? 分号左边改为引用即可 auto&

但是这里有个问题,万一是数组参数中的数组名会怎么样(这里就是指针了,无法确定数组的范围,就会报错)

//这里就不适合for范围的使用了,
void test2(int  a[])
{
	for (auto e : a)
	{
		cout << e << endl;
	}
}

空指针,以后使用nullptr就行

C++中的NULL解释为了 0,虽然不会出现什么错误,但是还是存在一点小问题

#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

例如:
在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
在 C++ 中,重载箭头运算符 `->` 实际上是重载了 `*` 运算符和 `->` 运算符。其中 `*` 运算符返回一个指向对象的指针,而 `->` 运算符用于访问该指针所指向对象的成员。因此,我们可以通过重载 `*` 运算符来返回一个自定义的指针类型,并重载 `->` 运算符来访问该指针所指向对象的成员。 以下是一个示例代码: ```c++ class MyClass { public: void func() { cout << "Hello, world!" << endl; } }; class MyPointer { private: MyClass* ptr; public: MyPointer(MyClass* p = nullptr) : ptr(p) {} MyClass* operator->() { return ptr; } }; class MyClassWrapper { private: MyClass obj; public: MyPointer operator->() { return MyPointer(&obj); } }; int main() { MyClassWrapper wrapper; wrapper->func(); // 输出 "Hello, world!" return 0; } ``` 在上面的代码中,我们首先定义了一个 `MyClass` 类,其中有一个成员函数 `func()`。然后,我们定义了一个 `MyPointer` 类,它包装了一个指向 `MyClass` 对象的指针,并重载了 `->` 运算符。在 `operator->()` 函数中,我们返回了一个指向 `MyClass` 对象的指针。最后,我们定义了一个 `MyClassWrapper` 类,它包装了一个 `MyClass` 对象,并重载了 `->` 运算符,返回一个 `MyPointer` 对象。 在 `main()` 函数中,我们创建了一个 `MyClassWrapper` 对象 `wrapper`,并通过 `wrapper->func()` 调用了 `MyClass` 对象的成员函数。由于 `MyClassWrapper` 对象重载了 `->` 运算符,因此调用 `wrapper->` 实际上会调用 `MyPointer` 对象的 `operator->()` 函数,该函数返回一个指向 `MyClass` 对象的指针,然后我们就可以通过该指针访问 `MyClass` 对象的成员函数了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

通过全部用例

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

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

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

打赏作者

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

抵扣说明:

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

余额充值