OpenCV4之C++入门详解 (上)

简介: OpenCV4之C++入门详解

OpenCV之C++入门


1、Visual Studio安装及环境配置与搭建


  1. 下载地址:https://my.visualstudio.com/Downloads?q=Visual,下载后按照说明安装即可


登录账号下载即可,建议下载Visual Studio 2017 专业版,本教程使用该版本完成
该教程笔记是本人整理的OpenCV学堂视频教程内容,感谢贾志刚老师的视频教程,下面是OpenCV 4.5.4及源码下载链接


链接:https://pan.baidu.com/s/1HmWrX35P774rr6tlfUXB2A 提取码:urtd


  1. 配置系统环境变量,鼠标右键我的电脑,选择属性,之后按下图操作,复制opencv目录下的bin目录,vs2017选择vc15

image.png


  1. 安装完毕后,新建第一个项目如下图

image.png


  1. 右键源文件选择新建项新建一个main.cpp


image.png

image.png


  1. 添加包含目录、库目录及附加依赖项

image.png

image.png

image.png

image.png

image.png


  1. 在D盘下新建一个images文件夹,放入一张图片,图片名与下面代码段中的图片名字一致

image.png


  1. 在main.cpp中输入以下代码


#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  Mat src = imread("D:/images/lena.jpg");
  imshow("input", src);
  waitKey(0);
  destroyAllWindows();
  return 0;
}


  1. 点击 调试开始调试 ,如果出现下图则表示运行成功,配置成功

image.png


至此,Visual Studio的准备工作完成!


2、图像基本操作


多行注释快捷键:Ctrl + K + Ctrl + C


2.1、图像读取与显示


#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
    //imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  Mat src = imread("D:/images/lena.jpg",IMREAD_GRAYSCALE);   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()){
    printf("could not load image...\n");
    return -1;
  }
  namedWindow("输入窗口",WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名,imshow()只支持显示8位图像及浮点图像
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


2.2、图像色彩空间转换


新建一个头文件quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
};


添加该项目包含目录为当前文件夹,操作如下


image.png

image.png

image.png


新建一个源文件quickdemo.cpp


#include<quickopencv.h>
void QuickDemo::colorSpace_Demo(Mat &image) {
  Mat gray, hsv;
  cvtColor(image, hsv, COLOR_BGR2HSV);
  // H 0~180 S 0~255 V 0~255
  cvtColor(image, gray, COLOR_BGR2GRAY);
  imshow("HSV", hsv);
  imshow("灰度", gray);
  imwrite("D:/images/hsv.png", hsv);
  imwrite("D:/images/gray.png", gray);
}


修改源文件test440,进行调试


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  //imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/lena.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
    //引入类QuickDemo,调用方法
  QuickDemo qd;
  qd.colorSpace_Demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.3、图像对象的创建与赋值


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
};


quickdemo.cpp


#include<quickopencv.h>
void QuickDemo::colorSpace_Demo(Mat &image) {
  Mat gray, hsv;
  cvtColor(image, hsv, COLOR_BGR2HSV);
  // H 0~180 S 0~255 V 0~255
  cvtColor(image, gray, COLOR_BGR2GRAY);
  imshow("HSV", hsv);
  imshow("灰度", gray);
  imwrite("D:/images/hsv.png", hsv);
  imwrite("D:/images/gray.png", gray);
}
void QuickDemo::mat_creation_demo() {
  //克隆和复制才会创建新的对象,赋值不会创建新的对象
  //Mat m1, m2;
  //m1 = image.clone();
  //image.copyTo(m2);
  // 创建空白图像
  Mat m3 = Mat::ones(Size(512, 512), CV_8UC3);
  m3 = Scalar(127, 127, 127); // 为像素赋予指定的值 B,G,R顺序
  std::cout << "width: " << m3.cols << " height: " << m3.rows << " channels: " << m3.channels() << std::endl;
  //std::cout << m3 << std::endl;
  Mat m4 = m3; //赋值后m4改变,会引起m3改变,clone或copyTo则会创建新对象,不影响原对象
  m4 = Scalar(0, 255, 255);
  imshow("创建图像", m3);
  Mat kernel = (Mat_<char>(3, 3) << 0,-1,0, // 3*3卷积核
    -1,5,-1,
    0,-1,0);
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/lena.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.mat_creation_demo();
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.4、图像像素的读写操作


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
      void pixel_visit_demo(Mat &image);
};


quickdemo.cpp


#include<quickopencv.h>
void QuickDemo::pixel_visit_demo(Mat &image) {
  int w = image.cols;
  int h = image.rows;
  int dims = image.channels();
  //for (int row = 0; row < h; row++) {
  //  for (int col = 0; col < w; col++) {
  //    if (dims == 1) { //灰度图像
  //      int pv = image.at<uchar>(row, col); //row,col → y,x
  //      image.at<uchar>(row, col) = 255 - pv; //对像素值反转,image.at<uchar>为获取某点格式为uchar的像素值
  //    }
  //    if (dims == 3) { //彩色图像
  //      Vec3b bgr = image.at<Vec3b>(row, col); //Vec3b为bgr图像像素点存储格式,对像素值进行反转
  //      image.at<Vec3b>(row, col)[0] = 255 - bgr[0];
  //      image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
  //      image.at<Vec3b>(row, col)[2] = 255 - bgr[2];
  //    }
  //  }
  //}
  for (int row = 0; row < h; row++) {
    uchar* current_row = image.ptr<uchar>(row); //获取当前行最初位置的指针
    for (int col = 0; col < w; col++) {
      if (dims == 1) { //灰度图像
        int pv = *current_row;
        *current_row++ = 255 - pv; //每次运算完,指针右移一位
      }
      if (dims == 3) { //彩色图像
        *current_row++ = 255 - *current_row; //由于bgr图像矩阵是连续的,所以指针直接指向下一位
        *current_row++ = 255 - *current_row;
        *current_row++ = 255 - *current_row;
      }
    }
  }
  imshow("像素读写演示", image);
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/lena.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.pixel_visit_demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.5、图像像素的算数操作


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
      void pixel_visit_demo(Mat &image);
      void operators_demo(Mat &image);
};


quickdemo.cpp


#include<quickopencv.h>
void QuickDemo::operators_demo(Mat &image) {
  Mat dst;
  Mat m = Mat::zeros(image.size(), image.type());
  m = Scalar(2, 2, 2); //Scalar标量
  //dst = image + Scalar(50, 50, 50);
  //dst = image - Scalar(50, 50, 50);
  //dst = image / Scalar(2, 2, 2);
  //加法手写实现,主要使用saturate_cast函数,运算可使用对应函数快速实现
  /*
  int w = image.cols;
  int h = image.rows;
  int dims = image.channels();
  for (int row = 0; row < h; row++) {
    for (int col = 0; col < w; col++) {
      Vec3b p1 = image.at<Vec3b>(row, col);
      Vec3b p2 = m.at<Vec3b>(row, col);
      //saturate_cast函数,将大于255的数转换为255,小于0的数转换为0
      dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0] + p2[0]);
      dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1] + p2[1]);
      dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);
    }
  }
  imshow("加法操作", dst);
  */
  //add(image, m, dst); //add(操作的图,对图片操作的参数,输出的结果)
  //subtract(image, m, dst); //减法
  //divide(image, m, dst); //除法
  multiply(image, m, dst); //乘法
  //imshow("加法操作", dst);
  //imshow("减法操作", dst);
  //imshow("除法操作", dst);
  imshow("乘法操作", dst);
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/dark_face.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.operators_demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.6、使用滚动条调整图像亮度(TrackBar)


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
    void pixel_visit_demo(Mat &image);
    void operators_demo(Mat &image);
    void tracking_bar_demo(Mat &image);
};


quickdemo.cpp


Mat src, dst, m;
int lightness = 50;
//回调函数两个形参,第一个int为createTrackbar中当前滑块所在位置,初始为lightness,第二个为userdata,为createTrackbar最后一个参数,默认为0
static void on_track(int, void*) {
  m = Scalar(lightness, lightness, lightness);
  add(src, m, dst);
  imshow("亮度调整", dst);
}
void QuickDemo::tracking_bar_demo(Mat &image) {
  namedWindow("亮度调整", WINDOW_AUTOSIZE);
  dst = Mat::zeros(image.size(), image.type());
  m = Mat::zeros(image.size(), image.type());
  src = image;
  int max_value = 100;
  //createTrackbar(滑动条名,滑动条所在的窗口,滑动块初始位置,滑动条最大值,回调函数(滑块滑动时的处理))
  createTrackbar("Value Bar:", "亮度调整", &lightness, max_value, on_track); 
  on_track(50, 0);
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/dark_face.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.tracking_bar_demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.7、滚动条操作-通过参数传递度


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
    void pixel_visit_demo(Mat &image);
    void operators_demo(Mat &image);
    void tracking_bar_demo(Mat &image);
};


quickdemo.cpp 对上一节函数优化


//回调函数两个形参,第一个int为createTrackbar中的当前滑块所在位置,第二个为userdata,为createTrackbar最后一个参数,默认为0
static void on_lightness(int b, void* userdata) {
  Mat image = *((Mat*)userdata);  //指针转换成Mat类型数据
  Mat dst = Mat::zeros(image.size(), image.type());
  Mat m = Mat::zeros(image.size(), image.type());
  addWeighted(image, 1.0, m, 0, b, dst);  //dst = image*1.0 + m*0 + b
  imshow("亮度与对比度调整", dst);
}
static void on_contrast(int b, void* userdata) {
  Mat image = *((Mat*)userdata);  //指针转换成Mat类型数据
  Mat dst = Mat::zeros(image.size(), image.type());
  Mat m = Mat::zeros(image.size(), image.type());
  double contrast = b / 100.0;
  //addWeighted()函数可以实现两张图片混合
  addWeighted(image, contrast, m, 0, 0, dst);  //dst = image*contrast + m*0 + 0
  imshow("亮度与对比度调整", dst);
}
void QuickDemo::tracking_bar_demo(Mat &image) {
  namedWindow("亮度与对比度调整", WINDOW_AUTOSIZE);
  int lightness = 50;
  int light_max_value = 100;
  int contrast_value = 100;
  int contrast_max = 200;
  //createTrackbar(滑动条名,滑动条所在的窗口,滑动块初始位置,滑动条最大值,回调函数(滑块滑动时的处理),userdata(传递给回调函数的数据))
  createTrackbar("Value Bar:", "亮度与对比度调整", &lightness, light_max_value, on_lightness, (void*)(&image));
  createTrackbar("Contrast Bar:", "亮度与对比度调整", &contrast_value, contrast_max, on_contrast, (void*)(&image));
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/dark_face.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.tracking_bar_demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.8、滚动条操作-键盘响应操作


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
    void pixel_visit_demo(Mat &image);
    void operators_demo(Mat &image);
    void tracking_bar_demo(Mat &image);
    void key_demo(Mat &image);
};


quickdemo.cpp


void QuickDemo::key_demo(Mat &image) {
  Mat dst = Mat::zeros(image.size(), image.type());
  while (true) {
    int c = waitKey(1); //waitKey(图像刷新时间间隔)不断刷新图像,刷新间隔时间为1ms,视频处理时尽量设置1ms
    if (c == 27) { // 退出
      break;
    }
    if (c == 49) { // Key #1
      cvtColor(image, dst, COLOR_BGR2GRAY);
      imshow("键盘响应01", dst);
    }
    if (c == 50) { // Key #2
      cvtColor(image, dst, COLOR_BGR2HSV);
      imshow("键盘响应02", dst);
    }
    if (c == 51) { // Key #3
      dst = Scalar(50, 50, 50);
      add(image, dst, dst);
      imshow("键盘响应03", dst);
    }
    //imshow("键盘响应", dst);
  }
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/lena.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.key_demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png


2.9、OpenCV自带颜色表操作


quickopencv.h


#pragma once
#include<opencv2/opencv.hpp>
using namespace cv;
class QuickDemo {
  public:
    void colorSpace_Demo(Mat &image);
    void mat_creation_demo();
    void pixel_visit_demo(Mat &image);
    void operators_demo(Mat &image);
    void tracking_bar_demo(Mat &image);
    void key_demo(Mat &image);
      void color_style_demo(Mat &image);
};


quickdemo.cpp


void QuickDemo::color_style_demo(Mat &image) {
  int colormap[] = {
    COLORMAP_AUTUMN,
    COLORMAP_BONE,
    COLORMAP_JET,
    COLORMAP_WINTER,
    COLORMAP_RAINBOW,
    COLORMAP_OCEAN,
    COLORMAP_SUMMER,
    COLORMAP_SPRING,
    COLORMAP_COOL,
    COLORMAP_PINK,
    COLORMAP_HOT,
    COLORMAP_PARULA,
    COLORMAP_MAGMA,
    COLORMAP_INFERNO,
    COLORMAP_PLASMA,
    COLORMAP_VIRIDIS,
    COLORMAP_CIVIDIS,
    COLORMAP_TWILIGHT,
    COLORMAP_TWILIGHT_SHIFTED
  };
  Mat dst;
  int index = 0;
  while (true) {
    int c = waitKey(2000);
    if (c == 27) {
      break;
    }
    applyColorMap(image, dst, colormap[index%19]);
    index++;
    imshow("颜色风格", dst);
  }
}


test440.cpp


#include<opencv2/opencv.hpp>
#include<quickopencv.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char**argv) {
  // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作
  // B,G,R
  Mat src = imread("D:/images/lena.jpg");   //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径
  if (src.empty()) {
    printf("could not load image...\n");
    return -1;
  }
  //namedWindow("输入窗口", WINDOW_FREERATIO);   //不管图片大小,都能进行调整,图像很小可以不使用这个函数
  imshow("输入窗口", src);                    //第一个参数为窗口名
  QuickDemo qd;
  qd.color_style_demo(src);
  waitKey(0);                               //窗口停留时间,0为一直停留,数值为停留的毫秒数
  destroyAllWindows();                      //关闭所有打开的窗口
  return 0;
}


效果


image.png

相关文章
|
30天前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
34 2
C++入门12——详解多态1
|
30天前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
73 1
|
20天前
|
存储 安全 编译器
【C++打怪之路Lv1】-- 入门二级
【C++打怪之路Lv1】-- 入门二级
16 0
|
20天前
|
自然语言处理 编译器 C语言
【C++打怪之路Lv1】-- C++开篇(入门)
【C++打怪之路Lv1】-- C++开篇(入门)
18 0
|
29天前
|
分布式计算 Java 编译器
【C++入门(下)】—— 我与C++的不解之缘(二)
【C++入门(下)】—— 我与C++的不解之缘(二)
|
29天前
|
编译器 Linux C语言
【C++入门(上)】—— 我与C++的不解之缘(一)
【C++入门(上)】—— 我与C++的不解之缘(一)
|
30天前
|
编译器 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
27 0
|
19天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
21 4
|
19天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
18 4
|
19天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
17 1