接上篇博客的内联函数:
内联函数声明和定义一定不要分离,分离会导致链接找不到,因为inline被展开就没有函数地址了,链接就会找不到。直接在.h定义就可以
auto关键字
int main()
{
int a = 0;
auto b = a;
return 0;
}
此代码的含义是:b的类型没有直接给出,而是通过推导得出的.
cout<<typeid(b).name()<<endl;
这行代码可以直接获取变量b的类型。
那auto看似鸡肋,有什么意义呢?
int main()
{
typedef map<string, string>::iterator DictIt;
//map<string, string>::iterator dit = dict.begin();
auto dit = dict.begin();
}
这就是auto的简化代码作用(注释与下面等效),类型很长时,可以考虑自动推导。
遍历数组的简便方式:范围for—语法糖
int main()
{
int arr[] = { 1,2,3,4,5 };
for (int i = 0; i < sizeof(arr) / sizeof(int);++i)
{
cout << arr[i] << " ";
}
cout << endl;
for (auto e : arr)
{
cout << e << " ";
}
cout << endl;
return 0;
}
两种代码等效。
语法糖:自动依次取数组中的数据赋值给e变量,自动判断结束。(e变量名是自己取的,也可以是其他字母)
但在语法糖中去改变e变量的值并不会改变数组的内容,若想改变数组的内容:
利可以用引用,这样就可以理解为e为数组中元素的别名了。
当同一行要定义多个变量,这一行的类型必须相同。
auto a=1,b=2;
auto a=1,b=2.0;
上述例子,第二行会编译失败。
另外auto不能作函数的形参,也不能来定义数组。
在c++中,有些情况下NULL在识别上会出现一些问题,例如某些情况下会被识别成整型(也就是0),所以 为保证代码的健壮性,之后都用nullptr代替。
题外话:为什么不取消NULL呢?在语言中有一个原则是,已经推出的语法就不能取消。
类
C++把结构体升级成了类。
类与结构体最大的不同是:类的内部可以定义函数。但在C++中,更喜欢用另一个关键字来代替struct----class。
类体由成员变量和成员函数构成。注意在类体的最后要加分号。
成员函数在定义时可以直接定义到类里面,也可以声明和定义分开。但注意,若分开要注意写法:
#pragma once
#include <stdlib.h>
// 类成员函数声明和定义分离
//struct Stack
class Stack
{
public:
// 成员函数
void Init(int capacity = 4);
void Push(int x);
private:
// 成员变量
int* a;
int size;
int capacity;
};
另外,在.cpp文件中调用成员函数还要注意加上::
void Stack::Init(int n)
访问限定符
public(公有) protect(保护) private(私有)
class默认的访问限定符是private,而struct的默认访问限定符是public(因为要兼容C)
一般情况下,一个类中成员变量是私有,成员函数想给别人用的部分为公有。成员变量习惯有一些符号防止调用函数无法区分,可能采用前边或后边加_。
类中的成员变量是声明而不是定义(因为没开空间)。当在主函数中实例化后才会开空间。
打个比方,类像楼房的计划图纸,而实例化后才是按照图纸建造出的楼房。
通过用sizeof查看类对象的大小我们发现,成员变量在对象中,而成员函数不在。
因为变量的存储不同,但函数可以公用。
即便这个类中没有成员变量,对象的大小也是1,用来占位。
但既然函数是公用的,传参不同的时候,又如何区分不同的对象所对应的不同的值呢?
实际上,编译器已经为我们处理了这一问题,所用的工具是this指针(我们看不到):
相当于把对象名称也传过去了。而this指针存在栈里。(不要弄混淆,函数的地址也就是指令地址,存在代码段中,而参数是指令运行产生的数据,存在于栈中)
另外,既然成员函数不在类中,那为什么不可以直接调用?
一是因为类域的限制,二是要传递this指针。