阿龙咖啡 /

Modern C++ 语言特性查漏补缺

const 修饰的成员函数

其本质是修改隐式this指针的类型,this指针将被认为是一个指向常量的指针

默认构造函数 (default constructor)

无需任何实参
对类成员执行默认初始化

合成的默认构造函数 (synthesized default constructor)

即由编译器创建的默认构造函数(default constructor)
只有当类没有声明任何构造函数时,编译器才会自动生成合成的默认构造函数
初始化:
若存在类内的初始值,用它来初始化成员
否则,对该成员执行默认初始化
合成的默认构造函数只适用于成员全部被赋予了类内初始值时

default 修饰的构造函数

相当于显式地让编译器生成合成的默认构造函数
若 “= default” 在类内,则此函数是内联的
若 “= default” 在类外,则此函数默认情况下 (即没有显式指定 inline) 不是内联的

数组指针 & 指针数组 & 返回数组指针的函数

int arr[10];  // 含有 10 个整数的数组
int *p1[10];  // 含有 10 个指针的数组
int (*p2)[10];  // 这是一个指针,指向含有 10 个整数的数组
auto func2(int i) -> int(*)[10];
int (*func(int i))[10];
// func(int i) 表示 func 函数需要 int 类型的实参
// (*func(int i)) 表示该函数的返回值可以被解引用
// (*func(int i))[10] 表示返回值被解引用后是大小是 10 的数组
// 注意这两种别名的区别
typedef int * intp;
typedef int inta[10];

cast 全家桶

static_cast

用于不包含底层 const,大转小的情况下使用(void * 指针转特定类型指针也可以用)

const_cast

const 与非 const 之间的互相转换

reinterpret_cast

基于底层的位模式的转换

dynamic_cast

【格式】:dynamic_cast < type-id > ( expression)
该运算符把expression转换成type-id类型的对象。Type-id可以是类的指针、类的引用或者void*。如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
【作用】:将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 即会作出一定的判断。
若对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
若对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。
【注意】:
1、dynamic_cast在将父类cast到子类时,父类必须要有虚函数,否则编译器会报错。
2、 dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

#include <iostream>
#include <cassert>
 
using namespace std;
 
// 我是父类
class Tfather
{
public:
    virtual void f() { cout << "father's f()" << endl; }
};
 
// 我是子类
class Tson : public Tfather
{
public:
    void f() { cout << "son's f()" << endl; }
 
    int data; // 我是子类独有成员
};
 
int main()
{ 
    Tfather father;
    Tson son;
    son.data = 123;
 
    Tfather *pf;
    Tson *ps;
    
    /* 上行转换:没有问题,多态有效 */
    ps = &son;
    pf = dynamic_cast<Tfather *>(ps);
    pf->f();
 
    /* 下行转换(pf实际指向子类对象):没有问题 */
    pf = &son;
    ps = dynamic_cast<Tson *>(pf);
    ps->f();
    cout << ps->data << endl;        // 访问子类独有成员有效
 
    /* 下行转换(pf实际指向父类对象):含有不安全操作,dynamic_cast发挥作用返回NULL */
    pf = &father;
    ps = dynamic_cast<Tson *>(pf);
    assert(ps != NULL);                 // 违背断言,阻止以下不安全操作
    ps->f();
    cout << ps->data << endl;        // 不安全操作,对象实例根本没有data成员
 
    /* 下行转换(pf实际指向父类对象):含有不安全操作,static_cast无视 */
    pf = &father;
    ps = static_cast<Tson *>(pf);
    assert(ps != NULL);
    ps->f();
    cout << ps->data << endl;        // 不安全操作,对象实例根本没有data成员
 
    system("pause");
}

留下一条评论

暂无评论