美文网首页
C++ 面试知识点

C++ 面试知识点

作者: 林逸凡_lyf | 来源:发表于2018-09-25 21:56 被阅读0次

    不定期整理一些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关键字用来防止单参数构造函数定义的隐式转换

    相关文章

      网友评论

          本文标题:C++ 面试知识点

          本文链接:https://www.haomeiwen.com/subject/twvdsftx.html