C++

C++面试知识点总结

2019-06-04  本文已影响0人  CurryCoder

技术交流QQ群:1027579432,欢迎你的加入!

一.static关键字的作用

1.静态成员的特点

2.静态成员和非静态成员的区别

3.静态成员函数的特点

二.C++和C的区别

三.c++中四种cast转换

四.C/C++ 中指针和引用的区别?

五.c++中的四个智能指针: shared_ptr,unique_ptr,weak_ptr,auto_ptr

六.野指针

七.为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数

八.函数指针

九.fork函数的作用

十.C++中析构函数的作用

十一.静态函数和虚函数的区别

十二.重载和重写

十三.虚函数和多态

十四.下面四个代码的区别const char * arr = "123"; char * brr = "123"; const char crr[] = "123"; char drr[] = "123";

十五.const修饰成员函数的目的是什么?

十六.C++里是怎么定义常量的?常量存放在内存的哪个位置?

十七.new/delete与malloc/free的区别是什么

十八.虚函数表具体是怎样实现运行时多态的?

十九.C语言是怎么进行函数调用的?

二十.C++如何处理返回值?

二十一.C++中拷贝赋值函数的形参能否进行值传递?

二十二.malloc与new区别

二十三.fork,wait,exec函数的作用

二十四.C++中类成员的访问权限

二十五. C++中struct和class的区别

二十六.C++类的内部可以定义引用数据成员吗?

二十七.什么是右值引用,跟左值又有什么区别?

二十八.C++源文件从文本到可执行文件经历的过程?

二十九.include头文件的顺序以及双引号””和尖括号<>的区别?

三十.什么时候会发生段错误?

三十一.C++11有哪些新特性?

三十二.const的作用

// 类
class A
{
private:
    const int a;                // 常对象成员,只能在初始化列表赋值

public:
    // 构造函数
    A() : a(0) { };
    A(int x) : a(x) { };        // 初始化列表

    // const可用于对重载函数的区分
    int getValue();             // 普通成员函数
    int getValue() const;       // 常成员函数,不得修改类中的任何数据成员的值
};

void function()
{
    // 对象
    A b;                        // 普通对象,可以调用全部成员函数、更新常成员变量
    const A a;                  // 常对象,只能调用常成员函数
    const A *p = &a;            // 常指针
    const A &q = a;             // 常引用

    // 指针
    char greeting[] = "Hello";
    char* p1 = greeting;                // 指针变量,指向字符数组变量
    const char* p2 = greeting;          // 常量指针即常指针,指针的指向可以改变,但是所存的内容不能变
    char const* p2 = greeting;     // 与const char* p2 等价
    char* const p3 = greeting;          // 指针常量,指针是一个常量,即指针的指向不能改变,但是指针所存的内容可以改变
    const char* const p4 = greeting;    // 指向常量的常指针,指针和指针所存的内容都不能改变,本质是一个常量
}

// 函数
void function1(const int Var);           // 传递过来的参数在函数内不可变
void function2(const char* Var);         // 参数为常量指针即指针所指的内容为常量不能变,指针指向可以改变
void function3(char* const Var);         // 参数为指针常量
void function4(const int& Var);          // 引用参数在函数内为常量

// 函数返回值
const int function5();      // 返回一个常数
const int* function6();     // 返回一个指向常量的指针变量即常量指针,使用:const int *p = function6();
int* const function7();     // 返回一个指向变量的常指针即指针常量,使用:int* const p = function7();

三十三.this 指针

三十四.inline内联函数

// 声明1(加 inline,建议使用)
inline int functionName(int first, int second,...);

// 声明2(不加 inline)
int functionName(int first, int second,...);

// 定义
inline int functionName(int first, int second,...) {/****/};

// 类内定义,隐式内联
class A {
    int doA() { return 0; }         // 隐式内联
}

// 类外定义,需要显式内联
class A {
    int doA();
}
inline int A::doA() { return 0; }   // 需要显式内联
#include <iostream>
using namespace std;
class Base
{
public:
    inline virtual void who()
    {
        cout << "I am Base\n";
    }
    virtual ~Base() {}
};
class Derived : public Base
{
public:
    inline void who()  // 不写inline时隐式内联
    {
        cout << "I am Derived\n";
    }
};

int main()
{
    // 此处的虚函数 who(),是通过类(Base)的具体对象(b)来调用的,编译期间就能确定了,所以它可以是内联的,但最终是否内联取决于编译器。
    Base b;
    b.who();

    // 此处的虚函数是通过指针调用的,呈现多态性,需要在运行时期间才能确定,所以不能为内联。
    Base *ptr = new Derived();
    ptr->who();

    // 因为Base有虚析构函数(virtual ~Base() {}),所以 delete 时,会先调用派生类(Derived)析构函数,再调用基类(Base)析构函数,防止内存泄漏。
    delete ptr;
    ptr = nullptr;

    system("pause");
    return 0;
}

三十五.volatile关键字

volatile int i=10;

三十六.assert()

#define NDEBUG          // 加上这行,则 assert 不可用
#include <assert.h>

assert( p != NULL );    // assert 不可用

三十七.sizeof()运算符

三十八.#pragma pack(n)

#pragma pack(push)  // 保存对齐状态
#pragma pack(4)     // 设定为 4 字节对齐

struct test
{
    char m1;
    double m4;
    int m3;
};

#pragma pack(pop)   // 恢复对齐状态

三十九. extern "C"

#ifdef __cplusplus
extern "C" {
#endif

void *memset(void *, int, size_t);

#ifdef __cplusplus
}
#endif

四十.struct 和 typedef struct

// c
typedef struct Student {
    int age;
} S;
// 等价于下面
struct Student {
    int age;
} ;
typedef struct Student S;

四十一.union联合体

四十二.explicit(显式)关键字

struct A
{
    A(int) { }
    operator bool() const { return true; }
};

struct B
{
    explicit B(int) {}
    explicit operator bool() const { return true; }
};

void doA(A a) {}

void doB(B b) {}

int main()
{
    A a1(1);        // OK:直接初始化
    A a2 = 1;       // OK:复制初始化
    A a3{ 1 };      // OK:直接列表初始化
    A a4 = { 1 };       // OK:复制列表初始化
    A a5 = (A)1;        // OK:允许 static_cast 的显式转换
    doA(1);         // OK:允许从 int 到 A 的隐式转换
    if (a1);        // OK:使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
    bool a6(a1);        // OK:使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
    bool a7 = a1;       // OK:使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
    bool a8 = static_cast<bool>(a1);  // OK :static_cast 进行直接初始化

    B b1(1);        // OK:直接初始化
    B b2 = 1;       // 错误:被 explicit 修饰构造函数的对象不可以复制初始化
    B b3{ 1 };      // OK:直接列表初始化
    B b4 = { 1 };       // 错误:被 explicit 修饰构造函数的对象不可以复制列表初始化
    B b5 = (B)1;        // OK:允许 static_cast 的显式转换
    doB(1);         // 错误:被 explicit 修饰构造函数的对象不可以从 int 到 B 的隐式转换
    if (b1);        // OK:被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool 的按语境转换
    bool b6(b1);        // OK:被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool 的按语境转换
    bool b7 = b1;       // 错误:被 explicit 修饰转换函数 B::operator bool() 的对象不可以隐式转换
    bool b8 = static_cast<bool>(b1);  // OK:static_cast 进行直接初始化

    return 0;
}

四十三.friend友元类和友元函数

四十四.:: 范围解析运算符

四十五.enum枚举类型

四十六.decltype关键字

四十七.引用和宏

四十八.必须使用成员初始化列表的场合

四十九.面向对象三大特征

五十.虚析构函数

五十一.纯虚函数

五十二.虚函数、纯虚函数

五十三.虚函数指针、虚函数表

五十四.虚继承

五十五.虚继承、虚函数

五十六.模板类、成员模板、虚函数

五十七.抽象类、接口类、聚合类

五十八.内存分配和管理

五十九.delete this 合法吗?

六十.如何定义一个只能在堆上(栈上)生成对象的类?

六十一.强制类型转换运算符(4种)

六十二.new delete和malloc free的联系和区别

六十三.hash冲突及解决方法

六十四.多态是什么,多态的作用?

六十五. 继承含有纯虚函数的父类,子类能否实例化?

六十六.构造函数是否可以用private修饰,如果可以,会有什么效果?

六十七.子类的指针能否转换为父类的指针?父类指针能否访问子类成员?

六十八.虚函数的实现机制

六十九.vector与list的区别

七十.vector的底层实现

七十一.函数参数压栈方式为什么是从右到左的?

七十二.动态库和静态库对比

七十三.预编译阶段的具体流程

七十四.黑盒测试与白盒测试

七十五.一个空类class中有什么?

七十六.构造函数和析构函数能被继承吗?

七十七.构造函数能不能是虚函数?

七十八.构造函数和析构函数能不能被重载 ?

上一篇 下一篇

猜你喜欢

热点阅读