C++ - fragment

std 中的 mapunordered_map 在 insert 的时候都会进行拷贝

一个小陷阱

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

int main()
{
char* temp = "sdf";
auto name = new char[10];
name = temp; // 这样赋值是错误的,因为 name 指是指向内存堆区的,如果使用 name = temp; 会造成指针指向改变不是指向堆区而是指向栈区,导致在后面调用析构函数 delete 释放空间出错!

std::cout << name << std::endl;
delete[] name;
return 0;
}

获取 class 的名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>

class AAAA
{
public:
void Test()
{
}
};

int main()
{
AAAA a;
const char* name = typeid(a).name();

std::cout << name << std::endl; // 输出结果 : class AAAA

// 这个方法不仅仅可以用于 class,还可以用于类方法
// 可以看出是那个类的方法
std::cout << typeid(&AAAA::Test).name() << std::endl; // 输出结果 :void (__thiscall AAAA::*)(void)

return 0;
}

判断 一个类 是不是 另外一个类 的子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<type_traits>
#include<iostream>

class BaseClass
{};

class SubClass : public BaseClass
{};

int main()
{
bool flag = std::is_base_of<BaseClass, SubClass>::value; // true
bool flag1 = std::is_base_of<SubClass, BaseClass>::value; // false
std::cout << flag << std::endl;
std::cout << flag1 << std::endl;
return 0;
}

生命周期

  • 超出生命周期范围就会被析构
  • 推荐使用智能指针
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <iostream>

    class Test
    {
    public:
    Test(int a, bool b)
    :a(a),b(b)
    {
    }
    void show()
    {
    std::cout << a << " - " << b << std::endl;
    }

    int a;
    bool b;
    };

    std::shared_ptr<Test> GetTestPrtInHeap1()
    {
    // 先 new 出来,再进行赋值
    Test* t = new Test(1, true);
    std::shared_ptr<Test> ret(t);
    return ret;
    }

    std::shared_ptr<Test> GetTestPrtInHeap2()
    {
    // 推荐方法
    return std::make_shared<Test>(2, false);
    }

    std::shared_ptr<Test> GetTestPrtInStack()
    {
    // 先构造出来,但是是再 stack 中
    // 函数结束就会被析构
    Test t(3, false);
    std::shared_ptr<Test> ret(&t);
    return ret;
    }

    int main()
    {
    auto ptr1 = GetTestPrtInHeap1();
    ptr1->show();
    //////////////////////

    auto ptr2 = GetTestPrtInHeap2();
    ptr2->show();

    //////////////////////
    auto empty_ptr = GetTestPrtInStack();
    empty_ptr->show();

    return 0;
    }

C++ 一个类的成员函数可以是模板函数么?

  • 不仅仅一个类的成员函数可以是 模板函数,一个模版类的成员函数也可以是 模板函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>

    class Print
    {
    public:
    template <typename T>
    static void print(const T& value)
    {
    std::cout << typeid(value).name() << " - " << value << std::endl;
    }
    };

    template <typename T1>
    class SuperPrint
    {
    public:
    template <typename T2>
    static void print(const T2& value)
    {
    std::cout << "super print ->" << typeid(value).name() << " - " << value << std::endl;
    }
    };

    int main()
    {
    Print::print(12);
    SuperPrint<int>::print(12);
    return 0;
    }

typeid 关键字

  • TypeId 返回一个变量或数据类型的“类型”。
    1
    2
    3
    cout<<typeid(int).name()<<endl; // int
    int a;
    cout<<typeid(a).name()<<endl; // int

多个返回值

  • C++ 多返回值函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <iostream>

    std::tuple<int, std::string, char*> testFunc()
    {
    int ret_int = 12;
    std::string ret_str = "ret_str";
    char* ret_char_ptr = "ret_char_ptr";
    return std::make_tuple(ret_int, ret_str, ret_char_ptr);
    }

    int main() {
    int ret_int;
    std::string ret_str;
    char* ret_char_ptr;

    tie(ret_int, ret_str, ret_char_ptr) = testFunc();
    std::cout << ret_int << std::endl;
    std::cout << ret_str << std::endl;
    std::cout << ret_char_ptr << std::endl;

    return 0;
    }