构造函数成员初始化列表
在C++中,构造函数成员初始化列表是一种在构造函数体执行之前初始化类成员变量的机制。这不仅能提高效率,还是初始化具有非默认构造函数的类成员、常量成员、引用成员和没有默认构造函数的基类的唯一方法。
构造函数成员初始化列表位于构造函数参数列表之后,函数体之前,以冒号开始,后面跟着一个或多个用逗号分隔的初始化器。每个初始化器都有一个成员变量名字和相应的初始化表达式,这个表达式可以是任意复杂度的。
下面是构造函数成员初始化列表的一个示例:
1 | class MyClass { |
在C++中,构造函数成员初始化列表是一种在构造函数体执行之前初始化类成员变量的机制。这不仅能提高效率,还是初始化具有非默认构造函数的类成员、常量成员、引用成员和没有默认构造函数的基类的唯一方法。
构造函数成员初始化列表位于构造函数参数列表之后,函数体之前,以冒号开始,后面跟着一个或多个用逗号分隔的初始化器。每个初始化器都有一个成员变量名字和相应的初始化表达式,这个表达式可以是任意复杂度的。
下面是构造函数成员初始化列表的一个示例:
1 | class MyClass { |
在C++中,对值的分类非常重要,因为它决定了你可以对这些值做什么操作。左值(lvalue)和右值(rvalue)是C++中的两种主要的表达式类别,而左值引用和右值引用则是与之对应的引用类型。
左值是指那些表达式,它们指向内存中的一个固定位置,这样的表达式可以出现在赋值语句的左侧。它们通常是一个变量、数组的一个元素或者一个对象的一个属性。左值可以取地址,即可以使用&运算符来得到其内存地址。
示例:
1 | int x = 10; // x是一个左值 |
在这个例子中,x是一个左值,因为你可以对它赋值。x具有一个持久的内存地址,可以在程序的多个地方引用和修改。
| 类型类别 | 类型名称 | 大小(位) | 取值范围 | 默认值 |
|---|---|---|---|---|
| 整数类型 | byte |
8 | -128 到 127 | 0 |
short |
16 | -32,768 到 32,767 | 0 | |
int |
32 | -2^31 到 2^31-1 | 0 | |
long |
64 | -2^63 到 2^63-1 | 0L | |
| 浮点数类型 | float |
32 | 精度约为 6-7 位十进制数 | 0.0f |
double |
64 | 精度约为 15 位十进制数 | 0.0d | |
| 字符类型 | char |
16 | 0 到 65,535(无符号) | |
| 布尔类型 | boolean |
未指定 | true 或 false |
false |
注意:
char类型是基于Unicode编码的,因此可以表示全球上几乎所有的字符。boolean并没有明确指定大小,但仅能取true或false中的一个值。C++的模板(Templates)和Java的泛型(Generics)都是用于实现代码的参数化类型,但是它们在设计理念、实现机制和功能上有很大的不同。下面是几个主要的区别:
Object。因此,在运行时是没有类型参数的具体信息的。在C++中,const关键字的位置相对于类型和星号(*,用于指针)或者引用符号(&)会影响它修饰的内容。这些不同的位置可以表示不同的含义,例如指针常量、常量指针、常量引用等。以下是const位置对含义的影响:
constconst在类型前:
1 | const int* ptr; |
这意味着ptr是一个指向const int的指针。你不能通过这个指针修改它指向的值,但是你可以修改指针ptr本身,使它指向另一个地址。
const在星号后:
1 | int* const ptr = &someIntVar; |
这意味着ptr是一个指向int的常量指针。你可以修改指针所指向的值,但是不能修改指针ptr本身的值,即不能让它指向另一个地址。这里,指针必须在声明时初始化,并且之后不能再指向其他地址。
const同时在类型前和星号后:
1 | const int* const ptr = &someIntVar; |
ptr是一个指向const int的常量指针。既不能通过指针修改所指向的值,也不能修改指针本身的值。
1 | 1. 虚函数允许派生类根据自己的需要重写基类的行为。在基类中,你通过在函数声明前加上virtual关键字来声明虚函数。 |
在C++中,成员函数的重写(override)是多态的一个核心概念,它允许派生类改变基类中某个函数的行为。对于虚函数来说,派生类确实可以直接重写基类中的虚函数。但是,对于非虚函数,派生类也可以提供自己的实现,这通常被称为隐藏(hiding)而不是重写。
我们来区分一下:
在Java和C++中,包含和访问库中的类型(如字符串)有不同的机制。
import语句:在Java中,当你使用import语句时,它告诉编译器在编译时需要查找哪些类。Java中的String类位于java.lang包中,该包是自动被所有Java程序导入的,因此你通常不需要显式导入java.lang.String。你可以直接使用String类而不需要任何前缀。
1 | import java.util.List; // 导入java.util包中的List接口 |
#include指令:在C++中,当你使用#include <string>预处理指令时,你是在告诉编译器在编译之前将<string>头文件的内容文本替换到源文件中。然而,C++标准库中的很多功能都是在命名空间std中定义的。
因此,当你包含<string>头文件后,你还需要使用std::的前缀来访问std命名空间中的string类。
在C++中,using关键字有几种用途,包括定义类型别名、引入命名空间中的名称,以及在C++11及后续版本中用于模板别名。以下是using关键字的几种常见用途:
和typedef一样,using可以用来给类型定义一个新的名称。这在C++11中引入,目的是为了提供一种比typedef更直观的语法来定义类型别名。
1 | using new_type_name = existing_type; |
1 | using Integer = int; |