不懂的知识点(不定时更新)

1.函数调用的压栈过程

入栈过程:函数参数从右向左入栈,函数运行状态入栈,函数返回地址入栈,代码区跳转(从当前代码区跳转到调用的函数入口)
出栈过程:保存返回值,弹出返回地址,返回值,弹出参数,跳转到原始地址
https://blog.csdn.net/u011555996/article/details/70211315

2.创建只有在堆/栈上生成的类

只能在堆上生成对象的类:

方案1:构造函数私有化

  1. 不能让这个类在栈上创建, 由于在栈上创建对象要直接调用构造函数, 如果我们把构造函数私有化, 就 无法在栈上创建对象了
  2. 那么我们又如何在堆上创建对象呢, 由于创建对象必定要调用构造函数, 在我们不定义其他构造函数时, 我们已经将两个默认构造函数已经私有, 在类外肯定是调用不到构造函数, 我们只有定义一个公有的静态成员函数 ,在其内部用new在堆区创建对象并返回其指针, (这里有很难以理解的一点, 在静态成员函数中用new 创建一个对象时, 也会调用构造函数, 我们知道, 静态成员函数不能调用成员函数, 那么new是如何调到构造函数的呢? 这得从静态成员函数为什么不能访问成员函数说起, 每一个对象都有一个隐含的this指针, 访问成员函数实际上时通过this指针调用的, 而在构造函数调用前还没有实例化出对象, 也就没有this指针, 所以构造函数不需要this指针调用, 静态成员函数也就可以调用构造函数了), 这点解释通了
#pragma once
class T1 {
    T1(int val):b(val) {
 
    }
    T1(T1& x):b(x.b){
        
    }
public:
    int b;
    static T1* newT1_p(int val = 0) {
        return new T1(val);
    }
    static T1& newT1(int val = 0) {
        return *new T1(val);
    }
};

方案2:析构函数私有化

将析构函数私有化, 在栈上也就不能直接创建对象了, 因为编译器在编译时会进行检测, 那没有析构函数也是不行的, 我们还需要实现一个函数来调用私有的析构函数, (这个思路就比构造函数私有好理解多了)

class T2 {
    ~T2() {
        delete this;
    }
public:
    int b;
    T2(int val = 0) :b(val) {
 
    }
    void Destroy() {
       this->~T2();
    }
};

只能在栈上生成的类

由于使用new进行申请会在堆上生成新类,因此将operator new 重载为私有函数即可。

class T3 {
    void* operator new(size_t val) {}
public:
    int a;
    T3(int val = 0) :a(val) {
 
    }
};

#include<iostream>
using namespace std;
 
int main() {
    T3 a;
    cout << a.a << endl;
    T3 b(10);
    cout << b.a << endl;
    system("pause");
    return 0;
}

https://blog.csdn.net/qq_41071068/article/details/102696312

3.排序算法时间复杂度

4.面向对象的三大特性,五大准则

三大特性
封装:将具体实现细节封装起来,留下外部接口供调用,保证安全性
继承:子类对父类属性和方法进行继承,减少了在内容扩展时的重构复杂度
多态:子类可对父类的属性和方法进行改写
五大原则
单一职责原则:每一个类只有一个引起其变化的变量
开放闭合原则:类对扩展开放,对修改封闭,保证在进行功能变更时不改变原有代码结构
里氏替换原则:所有存在父类的位置均可以使用子类进行替代
依赖倒置原则:高层次模块不应以来低层次模块,两者都应该依赖于抽象。
接口隔离原则:接口应小而完备,不应存在过多无用的属性和方法

5.x=x+1,x+=1,x++效率

x=x+1:1:读取右x的地址->2.x+1.做加1操作->3.读取左x的地址。->4.将右值传给左边的x(编译器并不认为左右x的地址相同)
x+=1:1:读取x的地址->2.x+1.做加1操作->3.将右值传给的x
x++:1.读取x地址->2.x自增

6.static和extern的区别

static是对变量进行定义,同时对其进行初始化;extern只是对变量或函数进行声明而非定义,编译时不会检查extern声明的对象,但是链接过程中如果未找到则会报错。

7.strcpy的风险

1.如果要拷贝的字符串长度大于原始字符串长度,则会发生越界
2.拷贝数组的时候结尾未出现‘/0’,则会越界复制
3.当拷贝的字符串是自身的一部分的时候可能会出错

strcpy返回值是拷贝后指针,增加灵活性。

8.DLL HELL

还未看
https://blog.csdn.net/qwertyupoiuytr/article/details/53999586

9.当拷贝构造函数使用值传递时会有什么错误

使用值传递的时候会调用拷贝构造函数生成一个该类的副本,但是拷贝构造函数使用值传递,会套娃,所以拷贝构造函数必须使用引用传递

10.virtual和static为什么不能同时作用于一个函数

1.static成员不属于任何类的对象,而是由类公用,因此加上virtual无意义
2.虚函数的调用关系:this -> vptr -> vtable ->virtual function。由于static函数没有this指针,因此无法进行虚函数访问。

11.vptr生成时间:

在基类构造函数之后,自身构造函数或初始化列表之前
构造函数调用虚函数:
派生类对象构造期间进入基类的构造函数时,对象类型变成了基类类型,而不是派生类类型。
同样,进入基类析构函数时,对象也是基类类型。

12.红黑树较AVL树的优点

黑树的查询性能略微逊色于AVL树,因为其比AVL树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的AVL树最多多一次比较,但是,红黑树在插入和删除上优于AVL树,AVL树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于AVL树为了维持平衡的开销要小得多

搜索次数多:AVL;查找次数多:红黑树

13.空类大小为什么是1

保证每个实例都有一个独特的地址,不会产生重复,编译器会给空类添加隐藏字节。

14.迭代器失效的情况及处理方法

顺序式容器:在进行删除操作后,删除节点之后的迭代器会失效,在删除之前将迭代器与初始位置的相对偏移记录,后续再做修改
关联式容器/链表式容器:只会使删除节点的迭代器失效,删除前做移动即可

15.同步异步,阻塞非阻塞

同步:主动等消息
异步:等人发消息
阻塞:等返回消息,返回前挂起
非阻塞:获得返回消息前先做别的事情
并发:一段时间内多个线程同时运行,但是同一时刻只能有一个线程
并行:平行线,多个线程同时运行

16.ping的过程

首先通过主机IP/掩码/目的主机IP检查是否在同一网段内

17.C++内存泄漏的几种情况

1.类的构造和析构函数中没有正确调用匹配的new和delete运算符
2.没有正确清除嵌套的对象指针
3.在释放对象数组时在delete中没有使用方括号
4.指向对象的指针数组不等同于对象数组
5.缺少拷贝构造函数
6.缺少重载赋值运算符
7.返回局部对象的引用或指针(野指针)
8.没有将基类的析构函数定义为虚函数

18.int fun() 和 int fun(void)的区别?

这里考察的是c 中的默认类型机制。

在c中,int fun() 会解读为返回值为int(即使前面没有int,也是如此,但是在c++中如果没有返回类型将报错),输入类型和个数没有限制, 而int fun(void)则限制输入类型为一个void。
在c++下,这两种情况都会解读为返回int类型,输入void类型。

19. 在C中用const 能定义真正意义上的常量吗?C++中的const呢?

不能。c中的const仅仅是从编译层来限定,不允许对const 变量进行赋值操作,在运行期是无效的,所以并非是真正的常量(比如通过指针对const变量是可以修改值的),但是c++中是有区别的,c++在编译时会把const常量加入符号表,以后(仍然在编译期)遇到这个变量会从符号表中查找,所以在C++中是不可能修改到const变量的。
补充:

1). c中的局部const常量存储在栈空间,全局const常量存在只读存储区,所以全局const常量也是无法修改的,它是一个只读变量。
2). 这里需要说明的是,常量并非仅仅是不可修改,而是相对于变量,它的值在编译期已经决定,而不是在运行时决定。
3).c++中的const 和宏定义是有区别的,宏是在预编译期直接进行文本替换,而const发生在编译期,是可以进行类型检查和作用域检查的。
4).c语言中只有enum可以实现真正的常量。
5). c++中只有用字面量初始化的const常量会被加入符号表,而变量初始化的const常量依然只是只读变量。
6). c++中const成员为只读变量,可以通过指针修改const成员的值,另外const成员变量只能在初始化列表中进行初始化。

下面我们通过代码来看看区别。
同样一段代码,在c编译器下,打印结果为*pa = 4, 4
在c++编译下打印的结果为 *pa = 4, 8

int main(void)
{
    const int a = 8;
    int *pa = (int *)&a;
    *pa = 4;
    printf("*pa = %d, a = %d", *pa, a);
    return 0;
}

20.模板函数和模板类的特例化

引入的原因:编写单一的模板,它能适应大众化,使每种类型都具有相同的功能,但对于某种特定类型,如果要实现其特有的功能,单一模板就无法做到,这时就需要模板特例化。
定义:是对单一模板提供的一个特殊实例,它将一个或多个模板参数绑定到特定的类型或值上。

函数模板特例化:必须为原函数模板的每个模板参数都提供实参,且使用关键字template后跟一个空尖括号对<>,表明将原模板的所有模板参数提供实参。

template<typename T> //函数模板
int compare(const T &v1,const T &v2)
{
    if(v1 > v2) return -1;
    if(v2 > v1) return 1;
    return 0;
}
//模板特例化,满足针对字符串特定的比较,要提供所有实参,这里只有一个T
template<>
int compare(const char const &v1,const char const &v2)
{
return strcmp(p1,p2);
}

模板类特例化:原理类似函数模板,不过在类中,我们可以对模板进行特例化,也可以对类进行部分特例化。对类进行特例化时,仍然用template<>表示是一个特例化版本,例如:

template<typename T>class Foo
{
    void Bar();
    void Barst(T a)();
};
template<>
void Foo<int>::Bar()
{
    //进行int类型的特例化处理
}

21.shared_ptr实现

#include <memory>
#include <iostream>
using namespace std;
 
template<typename T>
class smart{
private:
    T* _ptr;
    int* _count; //reference counting
public:
    //构造函数
    smart(T* ptr = nullptr):_ptr(ptr){
        if (_ptr){
            _count = new int(1);
        }
        else{
            _count = new int(0);
        }
    }
     
    //拷贝构造
    smart(const smart& ptr){
        if (this != &ptr){
            this->_ptr = ptr._ptr;
            this->_count = ptr._count;
             
            (*this->_count)++;
        }
    }
     
    //重载operator=
    smart operator=(const smart& ptr){
        if (this->_ptr == ptr._ptr){
            return *this;
        }
        if (this->_ptr){
            (*this->_count)--;
            if (this->_count == 0){
                delete this->_ptr;
                delete this->_count;
            }
        }
        this->_ptr = ptr._ptr;
        this->_count = ptr._count;
        (*this->_count)++;
        return *this;
    }
     
    //operator*重载
    T& operator*(){
        if (this->_ptr){
            return *(this->_ptr);
        }
    }
     
    //operator->重载
    T& operator->(){
        if (this->_ptr){
            return this->_ptr;
        }
    }
    //析构函数
    ~smart(){
        (*this->_count)--;
        if (*this->_count == 0){
            delete this->_ptr;
            delete this->_count;
        }
    }
    //return reference counting
    int use_count(){
        return *this->_count;
    }
};
 
int main(){
    smart<int> sm(new int(10));
    cout << "operator*():" << *sm << endl;
    cout << "reference counting:(sm)" << sm.use_count() << endl;
    smart<int> sm2(sm);
    cout <<"copy ctor reference counting:(sm)"<< sm.use_count() << endl;
    smart<int> sm3;
    sm3 = sm;
    cout <<"copy operator= reference counting:(sm)"<< sm.use_count() << endl;
    cout << &sm << endl;
    return 0;
}

22.虚函数使用模板函数会发生什么

使用模板函数时,程序在运行时会动态对模板进行参数类型匹配;而存在虚函数的类在编译时需要生成虚函数表,此时需要获得固定的虚函数类型,存在模板虚函数时编译器需要对全部程序进行遍历来确定一共存在多少实例化的虚函数,效率非常低下。

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