C++ 面试知识点

不定期整理一些C++的知识点

C++是静态类型,即在编译阶段检查类型

引用和const变量必须被初始化

多态是通过虚函数实现的,虚函数的实现机制是虚函数表,虚函数表一般存放在内存的最头部

const对象不能调用类中的非const成员函数,将成员变量定义为mutable(可变数据成员)可以使其在const成员函数中被修改(其作用是使成员变量对于外部类来说不能修改,但内部可以对其进行修改)

struct的默认访问权限是public,class则是private

解引用迭代器来获得它指向的元素(*itr),it->mem() == (*it).mem()

cout << *iter++ << endl; == cout << *(iter++) << endl;这种写法更加简洁,应该多使用

定义数组形参:

void print(int*, size_t size); 
void print(const int[], size_t size); 
void print(const int[10], size_t size); //因为无法判断数组的长度,所以需要把长度也作为形参
void print(int (&arr)[10]); //数组的引用作为形参必须加括号, 且数组确定
void print(int (*matrix)[10], int rowSize); //传入多维数组也必须加括号, 且第二维长度确定
void print(int matrix[][10], int rowSize);

使用initializer_list<T>来传入不定数量的形参:

void error_msg(initializer_list<string> il)
{
    for (auto beg = il.begin(); beg != il.end(); ++beg) {
        /* Do something */
    }
}

调用返回引用的函数得到一个左值

函数返回数组: auto func(int i) -> int(*)[10]; //c++11, 尾置返回类型

函数指针声明:

bool compare(const string&, const string&);
bool (*pf)(const string&, const string&);
pf = compare;
bool b1 = pf("hello", "world");
void useFunc(const string& s1, const string& s2, bool pf(const string&, const string&));
useFunc("hello", "world", compare);
auto fl(int) -> int (*)(int*, int*);

编译器为类对象生成的四个默认函数:构造函数,析构函数,拷贝构造函数,赋值运算符

vector便于访问,list便于插入删除

向泛型算法中传递谓词

bool isShorter(const string& s1, const string& s2) {
    return s1.size() < s2.size();
}
sort(words.begin(), words.end(), isShorter);

lambda函数
[capture list](parameter list)->return type {function body}, 其中参数列表和返回类型可忽略

auto f = [] { return 42; };
stable_sort(words.begin(), words.end(), [](const string& s1, const string& s2){ return s1.size() < s2.size() });
size_t sz = 100;
auto fz = [sz](const string& s1){ return s1.size() < sz }; // 函数拷贝捕获列表里的值而不是引用。
auto fs = [=, &](const string& s2){ return s1.size() < sz; } // 隐式捕获,=值捕获,&引用捕获

map会自动排序,无序关联容器使用unordered_map。map的底层实现是红黑树或AVL树,unordered_map的底层实现是哈希表

使用make_pair(key, value)来快速创建pair

程序中的内存包括静态内存(存储static成员),栈内存(存储非static对象,会自动销毁),堆内存(存储动态分配的对象,即在程序运行时分配的对象,生命周期由程序控制)

动态内存(堆)需要通过new和delete进行申请和释放

shared_ptr允许多个指针指向一个对象,unique_ptr独占对象

shared_ptr<int> p = make_shared(42); //创建一个指向42的指针
auto p2 = make_shared(10, '1');

拷贝构造函数,拷贝赋值运算符

// Foo中有一个string指针ps和int成员变量i
Foo(const Foo& f) //一般形参为const引用
    : ps(*f.ps)
    , i(p.i) {}
Foo& operator= (const Foo&); //形参为const引用,返回引用(*this)
Foo& Foo::operator= (const Foo&rhs) {
    auto newp = new string(*rhs.ps); //分配新地址
    delete ps; //释放旧地址
    ps = newp;  //将数据拷贝到本对象
    i = rhs.i;
    return *this;  //返回本对象
}
Foo(const Foo&) = delete; //阻止拷贝
Foo& operator= (const Foo&) = delete; //阻止赋值

重载输入输出运算符(不能是类的成员函数)

ostream& operator<<(ostream& os, const Foo& item) {
    os << item.isbn() << " " << item.name();
    return os;
}
istream& operator>>(istream& is, Foo& item) {
    is >> item.bookNo >> item.name;
    return is;
}

算数运算符形参一般是常量引用

Foo operator+(const Foo& lhs, const Foo& rhs) {  //非成员函数
    Foo sum = lhs;
    sum += rhs;  //也需要重新定义+=运算符
    return sum;    
}
Foo& Foo::operator+=(const Foo& rhs) {  //成员函数
    a += rhs.a;
    return *this;
}
bool operator==(const Foo& lhs, const Foo& rhs) {  //非成员函数
    return lhs.a() == rhs.a() && lhs.b() == rhs.b();
}
string& Foo::operator[](size_t n) { return vec[n]; }  //成员函数,同时定义常量和非常量类型
const string& Foo::operator[](size_t n) { return vec[n]; }
Foo& Foo::operator++() { ++a; return *this; }  //前置++,成员函数,返回新值
Foo Foo::operator++(int) { Foo tmp = *this; ++*this; return tmp; }  //后置++,成员函数,int形参,内部使用前置++实现,返回原值

基类的析构函数一般定义为虚函数,虚函数可能会在运行时才被解析

final关键字表示该类不能被继承,或是某函数不能被覆盖

模板,函数模板可以推断类型,但类模板必须显式指出类型

template <typename T> T foo(T* p) {
    T tmp = *p;
    // ...
    return tmp;
}
int i = 42;
int* p = &i;
i = foo(p);
template <typename T, typename U>
template <unsigned U> // 非类型参数模板
template <typename T> class Blob {} // 成员函数前也要加template关键字
Blob<int> prices;

explicit关键字用来防止单参数构造函数定义的隐式转换

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • 1. C++基础知识点 1.1 有符号类型和无符号类型 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值...
    Mr希灵阅读 17,978评论 3 82
  • 1.C和C++的区别?C++的特性?面向对象编程的好处? 答:c++在c的基础上增添类,C是一个结构化语言,它的重...
    杰伦哎呦哎呦阅读 9,514评论 0 45
  • 一、C语言基础 1、struct 的内存对齐和填充问题其实只要记住一个概念和三个原则就可以了: 一个概念:自然对齐...
    XDgbh阅读 2,208评论 1 38
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,515评论 1 51
  • “Just gonna stand there and watch me burn? That's all rig...
    雯熙_阅读 132评论 0 1