1. 使用const定义常量与用使用define定义常量相比,有什么优点?
- $const$常量有数据类型,而宏常量没有数据类型,编译器可以对前者进行类型安全检查,而后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误;
- 有些集成化的调试工具可以对$const$常量进行测试,但不能对宏常量进行测试
- $define$是在预处理阶段进行宏替换展开常量的,所以$define$定义常量会比$const$定义的常量消耗更多的内存
- 可以将$const$用于更复杂的类型中,比如常量数组,结构、类对象、指针、函数等
2. C++中如何进行静态类型转换,解释并举例说明。
- 用于基本数据类型之间的转换,如把$int$转换成$char$或$double$.
double d;
int a=16;
d=static_cast<double>(a);
- 用于类层次结构中基类和派生类之间指针或引用的转换。进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的
class Base { };
class Derived:public Base {};
int main()
{
Derived D;
Base* B = static_cast<Base*> (&D);
return 0;
}
3. 关键字const的用法有哪些?
总结为以下$8$种用法:
- 修饰一般常量和常数组
一般常量指相对简单类型($int$,$double/float$)的常量,这种常量在定义的同时也要进行初始化,$const$可放在类型说明符之前,也可以放在类型说明符之后。常数组和一般常量类似
const int x=2;
double const PI=3.14;
const int a[5]={1,2,3,4,5};
- 修饰常指针
$const$出现在星号左边,表示被指物是常量;
$const$出现在右边,指针自身是常量;
$const$出现在左右两边,被指物和指针自身是常量。
int a=1;
int *p=&a;//1.p可变,p指向的对象可变
int const *p;//2.const修饰指向的对象,p可变,p指向的对象不可变
const int *p;//3.const修饰指向的对象,p可变,p指向的对象不可变(与2相同)
int * const p=&a;//4.const修饰指针p,p不可变,定义时需要初始化,p指向的对象可变
const int *const p=&a;//5.指针p和指针p指向的对象均不可变
- 修饰常引用
使用$const$可以说明引用,该说明的引用为常引用,此时不能更新所引用的对象,经常将常引用作为函数的形参,这样不会发生对实参的误修改
int a=1;
const int& temp=a;
- 修饰常对象
常对象是指对象常量,定义常对象时,同样要进行初始化,并且该对象不能再被更新。
class A{
public:
A(int i,int j)
{
x=i;
y=j;
}
private:
int x,y;
};
A const a(1,2);
- 修饰函数的常参数
$const$修饰函数的传递参数,格式如下:
void fun(const A& a);
告诉编译器$a$在函数体中的无法改变,防止无意的或错误的修改,当调用该函数时用实参去初始化形参$a$。
- 修饰函数的返回值
$const$修饰函数的返回值,是返回值所指向或所引用的对象不可改变。
const A& fun1();
const A* fun2();
- 修饰类的成员属性
class A{
public:
static const int a;
const int b;
};
- 类属性$a$应在类外进行初始化
const int A::a=54;
- 类的对象属性$b$应在构造函数的初始化列表初始化
A::A():b(42){......};
- 修饰类的成员属性函数
class A{
public:
int Fun() const;
//......
};
调用函数$Fun$就不能修改类对象里面的数据
4. 在一个类中,为什么静态成员函数(static member function)中不能使用this指针?
参考于$OOP6$中问题$2$,此处为了方便将其复制过来
静态成员函数并不是针对某个类的实例对象,而是属于整个类的,为所有的对象实例所共有。它在作用域的范围内是全局的,独立于类的对象之外的。它只对类内部的静态成员变量做操作。当实例化一个类的对象时候,里面不存在静态成员的。$this$指针是相当于一个类的实例的指针,$this$是用来操作对象实例的内容的,既然静态成员函数和变量都是独立于类的实例对象之外的,它就不能用$this$指针。也不能操作非静态成员。
5. C++中,static静态变量的初始化和取值问题?
- 初始化: 类的静态成员初始化需要在全局空间内定义,在函数体内部定义静态成员变量生命周期和源程序相同,这个特点可以用来计算函数被调用的次数
- 取值问题: 默认不写为$0$