C++基础
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
static 作用 1. 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。 1. 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命令函数重名,可以将函数定位为 static。 1. 修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员。 1. 修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在 static 函数内不能访问非静态成员。
const 的作用 1. 修饰变量,说明该变量不可以被改变; 1. 修饰指针,分为指向常量的指针和指针常量; 1. 常量引用,经常用于形参类型,即避免了拷贝,又避免了函数对值的修改; 1. 修饰成员函数,说明该成员函数内不能修改成员变量。
内联函数的特点
相当于把内联函数中的内容复制到了调用该函数的地方(编译时完成);
相当于避免了函数调用的开销,直接执行函数体;
加速了程序的运行,但是消耗了空间
相当于宏,但比宏多了类型检查,使具有函数特性;
不能包含循环、递归、switch 等复杂操作;
如果包含了,那么相当于失去了内联的作用;
内联只是对编译器的建议,是否内联取决于编译器
定义在类中的函数,除了虚函数,都会自动隐式地当成内联函数。
内联函数通常定义在头文件中
inline 函数对编译器而言必须是可见的,以便它能够在调用点展开该函数。
如果定义在 cpp 文件中,那么在每个调用该内联函数的文件内都要再重新定义一次,且定义必须一致
inline 函数允许多次定义
inline
的使用
关于 inline 关键字应该放在声明还是定义处,重说纷纭,保险起见都加上
当然,最好的做法是直接定义在头文件中
将 inline 函数体复制到 inline 函数调用点处;
为所用 inline 函数中的局部变量分配内存空间;
将 inline 函数的的输入参数和返回值映射到调用方法的局部变量空间中;
如果 inline 函数有多个返回点,将其转变为 inline 函数代码块末尾的分支(使用 GOTO)。
优点(相比宏定义)
内联函数类似宏函数,在调用处展开,省去了调用开销(参数压栈、栈帧开辟与回收,结果返回等),从而提高程序运行速度。
相比宏函数来说,内联函数在代码展开时,会进行安全检查或自动类型转换(同普通函数),而宏定义不会。
在类中声明同时定义的成员函数,会自动转化为内联函数,因此内联函数可以访问类的成员变量,宏定义则不能。
内联函数在运行时可调试,宏定义不可以。
缺点
代码膨胀。
内联是以代码膨胀(内存)为代价,来消除函数调用带来的开销。
如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。
inline 函数无法随函数库升级。
inline 函数的改变需要重新编译,不像 non-inline 可以直接链接。
是否内联,程序员不可控。
内联函数只是对编译器的建议,是否对函数内联,决定权在于编译器。
虚函数可以是内联函数
但是当虚函数表现多态性时不能内联。
inline 是在编译期建议编译器内联,而虚函数的多态性在运行期,编译器无法知道运行期调用哪个代码,因此虚函数表现为多态性时(运行期)不可以内联。
虚函数唯一可以内联的情况是:
编译器知道所调用的对象是哪个类,如
Base::who()
,这只有在编译器具有实际对象而不是对象的指针或引用时才会发生。
虚函数的内联
断言 assert()
是宏而非函数,定义在头文件 <assert.h>/<cassert>
中
sizeof()
是操作符而非函数 sizeof int == sizeof(int)
sizeof 对数组,得到整个数组所占空间大小。
sizeof 对指针,得到指针本身所占空间大小。
特别的
C 中的结构体
等价于
实际上就是为 struct Student
这个比较长的声明定义了一个别名 Stu
因为 C 中定义结构体,必须带上 struct
,所以还可以定义 void Student() {}
不冲突
C++ 中的结构体
如果定义了同名的函数,那么 struct 关键字不可省略
一般来说,struct 适合作为一个数据结构的实现体,class 更适合作为一个对象的实现体
但最本质的区别在于默认的访问控制权限
默认的继承访问权限—— struct 是 public,class 是 private
默认的成员访问权限—— struct 是 public,class 是 private
联合体(union)是一种节省空间的特殊的类
一个 union 可以有多个数据成员,但是在任意时刻只有一个数据成员可以有值
当某个成员被赋值后其他成员变为未定义状态
联合体的特点
默认访问控制符为 public
可以含有构造函数、析构函数
不能含有引用类型的成员
不能继承自其他类,不能作为基类
不能含有虚函数
匿名 union 在定义所在作用域可直接访问 union 成员
匿名 union 不能包含 protected 成员或 private 成员
全局匿名联合必须是静态(static)的
友元小结
能访问私有成员
破坏封装性
友元关系不可传递
友元关系的单向性
友元声明的形式及数量不受限制
友元函数
不是类的成员函数,却能访问该类所有成员(包括私有成员)的函数
类授予它的友元函数特别的访问权,这样该友元函数就能访问到类中的所有成员。
友元类
一个类的友元类可以访问该类的所有成员(包括私有成员)
注意点
友元关系不能被继承
友元关系不能传递
友元关系是单向的
```Cpp
class A {
public:
friend class C; // 友元类的声明:C 是 A 的友元类
private:
int data;
};
class C { // 友元类的定义,可以访问 A 中的成员 public: void set_A_data(int x, A &a) { a.data = x; }
};
int main(void) { class A a; class C c;
}
限制作用域的枚举类型,使用关键字
enum class
不限作用域的枚举类型
但这不代表虚函数无法内联 >
- C++ FAQ
董的博客 »
- zhuguanhao - 博客园
_百度搜索