Administrator
发布于 2023-11-05 / 12 阅读 / 0 评论 / 0 点赞

C++ 知识点 专题

11月5日
基类构造函数调用纯虚函数和创建顺序
template<class T>
class Head{//abstrast
    std::vector<T> myhead;
    virtual bool compareto(int a,int b)=0;
    void siftDown(int i){
        while (true) {
            int l=left(i),r=right(i),t=i;
            // if(l<size() && myhead[t]<=myhead[l]){
            if(l<size() && compareto(t, l)){
                t=l;
            }
            // if(r<size() && myhead[t]<=myhead[r]){
            if(r<size() && compareto(t, r)){
                t=r;
            }
            if(t==i)
                break;
            std::swap(myhead[i],myhead[t]);
            i=t;
        }
    }


public:
    Head(std::vector<T> vec){
        myhead=vec;
        for(int i=size()-1;i>=0;i--){
            siftDown(i);//---------------简介调用纯虚函数
        }
    }
    
};

class MaxHead:public Head<T>{
    virtual bool compareto(int a,int b)override {
        return myhead[a]<=myhead[b];
    }
};
-----------------
Test
    std::vector<int> vec={12,34,34,45,13,43,123,3};
    MaxHead<int> h(vec);//xxxxxxx报错

错误原因:

构建MaxHead对象时,会先创建Head部分,先执行Head的构造函数,此时MaxHead的部分并没有创建,MaxHead重写的compareto还没有构造。

因此Head的构造函数会调用基类的compareto函数,最后报错尝试执行纯虚函数

解决方法:

不要在父类的构造函数中尝试调用子类的方法

template<class T>
class Head{//abstrast
    std::vector<T> myhead;
    virtual bool compareto(int a,int b)=0;
    void siftDown(int i);


public:
    Head(std::vector<T> vec){
        myhead=vec;
    //  for(int i=size()-1;i>=0;i--){
    //      siftDown(i);//---------------简介调用纯虚函数
    //  }
    }
    
};

class MaxHead:public Head<T>{
    virtual bool compareto(int a,int b)override {
        return myhead[a]<=myhead[b];
    }
public:
    MaxHead(std::vector<T> vec):Head<T>(vec){
        for (int i=this->myhead.size()-1; i>=0; i--) {
            this->siftDown(i);
        }
    }
};
-----------------
Test
    std::vector<int> vec={12,34,34,45,13,43,123,3};
    MaxHead<int> h(vec);// VVVVVVVV

CMake生成动态库

cmake_minimum_required(VERSION 3.0.0)
project(t1 VERSION 0.1.0 LANGUAGES C CXX)

include(CTest)
enable_testing()

add_library(t1 t1.cpp) # !!!!!

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

add_library

加入头文件和链接动态库
cmake_minimum_required(VERSION 3.0.0)
project(t2 VERSION 0.1.0 LANGUAGES C CXX)

include(CTest)
enable_testing()

# set(t1_DIR ../../t1/build)
# find_package(t1 REQUIRED)
include_directories(/root/code/course/tmp/t1/include) #加入该目录所有头文件

add_executable(t2 main.cpp)

# 链接动态库
target_link_libraries(t2 PRIVATE /root/code/course/tmp/t1//build/libt1.a)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

c++2维数组初始化问题
        int m=matrix[0].size(),n=matrix.size();
        vector<vector<int>> dp(n, vector<int>(m, 0));

c++多线程

CS_Offer/Linux_OS at master · selfboot/CS_Offer · GitHub (githubfast.com)

c++fork()问题

线程的共享资源
  • 进程代码段、

  • 进程的共有数据、

  • 进程打开的文件描述符

  • 信号的处理器

  • 进程的当前id、用户id、进程组id

线程之间的资源

独立的栈堆、局部变量

在同一进程下的多个线程,它们共享以下资源:

  1. 内存空间:所有线程都可以访问进程的地址空间,包括代码段、数据段和堆栈段。这意味着线程可以读取和修改相同的变量,以及共享动态分配的内存。

  2. 文件描述符:文件描述符是打开文件或套接字的引用,它们在进程级别是共享的。因此,多个线程可以同时读取或写入相同的文件或套接字。

  3. 共享库和全局变量:多个线程可以同时访问和使用进程加载的共享库和全局变量。

另外,每个线程也有自己的资源,包括:

  1. :每个线程都拥有自己的栈空间,用于存储局部变量、函数调用和返回地址等。

  2. 寄存器值:线程在执行时会使用寄存器来保存临时变量和执行上下文。寄存器是线程私有的,不会被其他线程访问或修改。

  3. 线程特定数据(Thread-Local Storage, TLS):每个线程可以拥有自己的线程特定数据,它们是线程私有的全局变量,对其他线程不可见。

线程的轮转法

有4个进程A,B,C,D,设它们依次进入就绪队列,因相差时间__牛客网 (nowcoder.com)

此题,IO可抢占,cpu可抢占

c++volatile

volatile修饰变量,告诉系统每次读取该变量时一定要从该变量的内存中读取。避免因为系统优化使得读到的是缓存中的值而引起的不必要麻烦

sizeof()

  • sizeof 对数组,得到整个数组所占空间大小。

  • sizeof 对指针,得到指针本身所占空间大小。

c++尽量使用成员初始化器

  • 在构造器里初始化:

X(); 先默认构造

X& operator=(int) 再赋值函数

  • 在成员初始化列表里出初始化

X(int); 直接构造

使用成员初始化列表效率更高

可读性更好

错误仅仅是是指低效复杂,


评论