c++的一些陌生用法记录

1. 完美转发std::forward<decltype(PH1)>(PH1)

在这里插入图片描述

2. static的用法

  1. static函数与普通函数的区别: 用static修饰的函数,本限定在本源码文件中,不能被本源码文件以外的代码文件调用。 而普通的函数,默认是extern的,也就是说,可以被其它代码文件调用该函数。 在函数的返回类型前加上关键字static,函数就被定义成为静态函数

  2. 不用实例化对象就可以调用类中的静态成员函数。如果没有实例化对象,直接调用类的非静态函数会报类似cannot call member function ’A()‘ without object;

  3. 需要注意,一个变量或者函数在同一个工程中,不能同时使用static和extern关键字修饰。因为在 C/C++ 中,extern 关键字用于声明一个全局变量或函数是在其他文件中定义的,而 static 关键字则用于声明一个变量或函数是在当前文件中定义的,只在当前文件的作用域内可见。因此,同一个变量或函数不能同时被声明为 extern 和 static。

3. placement new的用法

placement new 可以在地址没有确定的情况下构建对象。

placement new 是一种特殊的 new 操作符,它允许你在已经分配了内存的地址上构建对象,而不是让 new 操作符分配内存。通常情况下,你会手动分配内存,然后使用 placement new 在这个已分配的内存上构建对象。

由于 placement new 不涉及内存分配,而是使用你提供的地址进行构建,因此你可以在编译时并不知道确切地址的情况下使用它。这种灵活性使得它在某些情况下非常有用,比如在特定的内存池中构建对象,或者在堆栈上分配对象

char singBuf[sizeof(Sing)]; // 编译器将为singBuf分配一块内存,但具体地址尚未确定

// 在singBuf的内存上使用placement new构建Sing对象
Sing* singPtr = new (singBuf) Sing();

这种情况下,singBuf是一个字符数组,其内存地址由编译器分配,但是具体地址在编译时尚未确定。你可以使用 placement new 在这个数组的内存上构建对象,因为编译器会为 new (singBuf) Sing() 提供所需的地址信息

4. const容易遗忘的点

  1. 我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数,而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。 const成员函数和const对象 实际上,const成员函数还有另外一项作用,即常量对象相关。对于内置的数据类型,我们可以定义它们的常量,用户自定义的类也一样,可以定义它们的常量对象。
  • 非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误)
  • 表示成员函数隐含传入的this指针为const指针,决定了在该成员函数中,
    任意修改它所在的类的成员的操作都是不允许的(因为隐含了对this指针的const引用);
  • 唯一的例外是对于mutable修饰的成员。
    加了const的成员函数可以被非const对象和const对象调用
    但不加const的成员函数只能被非const对象调用

5. Vector push_back 的时候使用std::move的益处

在这里插入图片描述

6. 数组的遍历方式性能

力扣79题的耗时对比:
使用索引遍历时间超过1000ms。使用范围base遍历,时间100多ms

6.1 索引遍历和范围base遍历的性能

本地vs debug模式性能对比:
索引遍历: 2.2s
范围base遍历: 6.5s

#include<vector>
#include<iostream>
#include<chrono>

using namespace std;

class Solution {
public:

    vector<vector<int>> dxy{ {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
    bool process(vector<vector<char>>& board, string& word, int c, int r, int t, int m, int n, vector<vector<bool>>& vis)
    {
        if (t == word.size() - 1)
        {
            return true;
        }

         for(int i = 0; i < 4; i++)
        //for (auto xy : dxy)
        {
            int nc = c + dxy[i][0];
            int nr = r + dxy[i][1];
            if (nc < 0 || nc >= m || nr < 0 || nr >= n || vis[nc][nr] || board[nc][nr] != word[t + 1]) continue;
            vis[nc][nr] = true;
            if (process(board, word, nc, nr, t + 1, m, n, vis)) return true;
            vis[nc][nr] = false;
        }
        return false;
    }

    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size();
        int n = board[0].size();
        vector<vector<bool>> vis(m, vector<bool>(n, false));

        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (board[i][j] != word[0]) continue;
                vis[i][j] = true;
                if (process(board, word, i, j, 0, m, n, vis)) return true;
                vis[i][j] = false;
            }
        }
        return false;
    }
};

int main()
{
    vector<vector<char>> dp =  {{ 'A','A','A','A','A','A'},
                                {'A','A','A','A','A','A'},
                                {'A','A','A','A','A','A'},
                                {'A','A','A','A','A','A'},
                                {'A','A','A','A','A', 'B'},
                                {'A','A','A','A', 'B','A'}};
    string ss = "AAAAAAAAAAAAABB";
    auto start = std::chrono::high_resolution_clock::now();

    Solution S;
    S.exist(dp, ss);

    auto end = std::chrono::high_resolution_clock::now();

    std::chrono::duration<double> elapsed = end - start;

    std::cout << "程序运行时间:" << elapsed.count() << " 秒" << std::endl;
    return 0;
}

在这里插入图片描述

6.2 静态数组和动态数组的索引遍历性能和初始化方式

在这里插入图片描述

在这里插入图片描述

6.3 类的成员变量初始化方式注意

  • 不合法
    因为这种形式的初始化只能在构造函数或成员函数中使用,而不能在类的成员变量处进行。
class Solution
{
	vector<vector<int>> m_vis(6, vector<int>(6, 0)); 
};
  • 合法(在)
    可以在构造函数中初始化vis数组,或者将其声明为成员变量后在构造函数中进行初始化
class Solution
{
	vector<vector<int>> m_vis; 
	Solution(): (6, vector<int>(6, 0)){}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星光技术人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值