c++笔记

 1.类的快速调用

#pragma once

#include <QObject>

#ifndef RIW
#define RIW RulerInfoWrap::Instance()
#endif

class RulerInfoWrap : public QObject {
    Q_OBJECT

public:
    static RulerInfoWrap* Instance();

public:
    RulerInfoWrap(QObject* parent = nullptr);

    ~RulerInfoWrap();

public:
    void init();
};
//.cpp文件

#include "RulerInfoWrap.h"
#include <QDebug>
RulerInfoWrap* RulerInfoWrap::Instance()
{
    qDebug() << "RulerInfoWrap::Instance()";
    static RulerInfoWrap* ruler = new RulerInfoWrap();
    return ruler;
}

RulerInfoWrap::RulerInfoWrap(QObject* parent)
    : QObject(parent)
{
    qDebug() << "RulerInfoWrap::RulerInfoWrap()";
}

RulerInfoWrap::~RulerInfoWrap()
{
    qDebug() << "RulerInfoWrap::~RulerInfoWrap()";
}
void RulerInfoWrap::init()
{

    qDebug() << "RulerInfoWrap::init()";
}

在其他文件中调用时只需要引用其头文件#include "RulerInfoWrap.h"然后

    RIW->init();
     delete RIW;
//打印如下:
RulerInfoWrap::Instance()
RulerInfoWrap::RulerInfoWrap()
RulerInfoWrap::init()
RulerInfoWrap::Instance()
RulerInfoWrap::~RulerInfoWrap()

2.创建目录


获取当前工作目录的路径:
    QString path = QDir::currentPath() + "/config/serial_port.json";

QFileInfo fileInfo(path);
    QDir dir = fileInfo.dir();
    if (!dir.exists()) {
        dir.mkpath(dir.absolutePath());
    }
   这段代码的功能是:给定一个文件路径,检查该文件所在的目录是否存在。
如果不存在,则创建这个目录及其所有必要的父目录。
这在确保文件可以被保存到一个预期的目录结构中时非常有用,
尤其是在应用程序需要自动管理其数据存储目录时。


QFileInfo fileInfo(path);
这行代码创建了一个QFileInfo对象,名为fileInfo。
QFileInfo类提供了关于文件的信息,比如文件的大小、创建时间、修改时间等。
这里,它被用来获取与给定路径path相关联的文件的信息

QDir dir = fileInfo.dir();
这行代码从fileInfo对象中获取文件所在的目录,并创建了一个QDir对象dir。
QDir类用于操作目录和目录路径,提供了创建、删除、重命名目录以及列出目录内容等功能。
fileInfo.dir()返回的是文件所在目录的QDir对象。

if (!dir.exists()) 
这行代码检查由fileInfo.dir()返回的目录是否存在。

dir.mkpath(dir.absolutePath());
如果目录不存在,这行代码将创建该目录。
dir.mkpath()是一个方法,用于创建由dir指定的路径,包括任何必要的父目录。
dir.absolutePath()返回dir对象的绝对路径,即完整的目录路径。
这意味着,如果dir是一个相对路径,mkpath会基于当前工作目录或绝对路径来创建整个目录结构。

3.json文件

3.1 写操作

将如下的Json字符串写入到文件中:

  1. 创建一个QJsonOBject对象,将各个键值对设置进QJsonOBject对象中
  2. 将QJsonOBject对象转换为QJsonDocument对象
  3. QJsonDocument对象在转换为QByteArry对象中。
  4. 通过文件操作写入到文件中
    /*
    {
        "Name":"lisa",
         "Age":20,
        //Family中的value值是一个Json对象
        "Family":{
            "Father":"Gol·D·Roger",
            "Mother":"Portgas·D·Rouge",
            "Brother":["Sabo", "Monkey D. Luffy"]
        },
        "IsAlive":false,
        "Comment":"yyds"
    }
    */
     
     
    void qjson_write()
    {
        QJsonObject value;
        value.insert("Name","lisa");
        value.insert("age",20);
     
        /*
          封装:
          "Family":{
            "Father":"Gol·D·Roger",
            "Mother":"Portgas·D·Rouge",
            "Brother":["Sabo", "Monkey D. Luffy"]
           }
       */
        QJsonObject family_value;
        family_value.insert("Father","Gol·D·Roger");
        family_value.insert("Mother","Portgas·D·Rouge");
        QJsonArray bro_arry;
        bro_arry.push_back(QJsonValue("Sabo"));
        bro_arry.push_back(QJsonValue("Monkey D. Luffy"));
        family_value.insert("Brother",bro_arry);
     
        value.insert("Family",family_value);
        value.insert("IsAlive",false);
        value.insert("Comment","yyds");
     
        QJsonDocument document(value);
        QByteArray s=document.toJson();
     
        QFile file("E:\\test1.json");
     
        file.open(QFile::WriteOnly);
        file.write(s);
        file.close();
    }
    bool Utils::WriteJsonFile(QString path, QJsonObject json)
    {
        // 写入Json文件到指定路径,路径不存在则创建
        QFileInfo fileInfo(path);
        QDir dir = fileInfo.dir();
        if (!dir.exists()) {
            dir.mkpath(dir.absolutePath());
        }
        QFile file(path);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            qWarning() << "打开:" << path << "失败";
            return false;
        }
        QJsonDocument doc(json);
        file.write(doc.toJson());
        return true;
    }

    3.2 读操作

  5. 将上面的文件给读取到QJsonDocument,并转换为QJsonObject.
  6. 将其中键值为 age,Name 和 Comment的进行打印。
    void qjson_read()
    {
        //打开文件,并读取Json字符串
        QFile file("E:\\test1.json");
        file.open(QFile::ReadOnly);
        QByteArray s=file.readAll();
        file.close();
     
        //将Json字符串转换为QJsonDocument对象
        QJsonDocument document=QJsonDocument::fromJson(s);
     
        QJsonObject object;
        if(document.isObject()){
             object=document.object();
        }
     
        //获取所有的key值
        QStringList keys=object.keys();
       // qDebug()<<object.size();
       //遍历QJsonObject中所有的键值对
        for(int i=0;i<object.size();i++)
        {
            QString key=keys.at(i);
            QJsonValue value=object[key];
     
            if(value.isDouble())
            {
                int v=value.toInt();
                qDebug()<<key<<v;
            }
            else if(value.isString())
            {
                QString s=value.toString();
                qDebug()<<key<<s;
            }
        }
     
    }
    std::optional<QJsonObject> Utils::ReadJsonFile(QString path)
    {
        // 加载Json文件
        QFile file(path);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qWarning() << "打开:" << path << "失败";
            return { std::nullopt };
        }
    
        QJsonParseError error;
        QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
        if (doc.isNull()) {
            qWarning() << "Failed to create JSON doc." << error.errorString();
            return { std::nullopt };
        }
        return { doc.object() };
    }
    

    4.获取ui值转化

        4.1ui.hz->currentData().value<QSerialPort::BaudRate>();

这行代码是在使用Qt框架进行编程时可能遇到的一种用法,特别是在处理与串行端口(QSerialPort)相关的UI组件时。下面是对这行代码的详细解释:

  1. ui.hz:
    • ui 通常是一个用户界面(UI)对象,它是在使用Qt Designer设计界面时自动生成的,或者通过手动编码创建。
    • hz 可能是ui对象中的一个成员,通常是一个下拉框(QComboBox)、列表视图(QListView)或其他可以选择项目的控件。
  2. currentData():
    • 这个方法通常用于获取当前选中项的数据。在Qt中,像QComboBox这样的控件提供了currentData()方法,用于返回与当前选中项相关联的数据。
    • 需要注意的是,currentData()返回的类型是QVariant,这是Qt中一个非常通用的数据类型,可以存储各种不同类型的数据。
  3. value<QSerialPort::BaudRate>():
    • value<T>()QVariant类的一个模板方法,用于将QVariant转换为特定类型T的值。
    • 在这个例子中,TQSerialPort::BaudRate,这是Qt中定义的一个枚举类型,表示串行端口的波特率(如9600、115200等)。
    • 因此,value<QSerialPort::BaudRate>()QVariant转换为QSerialPort::BaudRate类型的值。

综上所述,这行代码的作用是:从用户界面控件ui.hz中获取当前选中项的数据,并将其转换为QSerialPort::BaudRate类型的值。这通常用于配置串行端口的通信参数,例如,用户可能从一个下拉框中选择所需的波特率,然后程序使用该波特率来配置串行端口。

5.单例模式

5.1代码

#pragma once

#include <QObject>

#include "Ruler.h"

#ifndef RIW
#define RIW RulerInfoWrap::Instance()
#endif

class RulerInfoWrap : public QObject {
    Q_OBJECT

public:
    static RulerInfoWrap* Instance();
private:
    RulerInfoWrap(QObject* parent = nullptr);

    ~RulerInfoWrap();
};




#include "pch.h"

#include "RulerInfoWrap.h"

#include <QSqlField>

#include "QDataWrap.h"
#include "QtUtils.h"

RulerInfoWrap* RulerInfoWrap::Instance()
{
    static RulerInfoWrap* ruler = new RulerInfoWrap();
    return ruler;
}

RulerInfoWrap::RulerInfoWrap(QObject* parent)
    : QObject(parent)
{
}
RulerInfoWrap::~RulerInfoWrap()
{
}

引用:
    auto&& opt = RIW->addRuler(ruler);

5.2代码

class Printer
{

private:
    //1.定义一个静态的 对象指针变量 保存唯一示例地址
    static Printer *signlePrint;
public:
    //2.提供一个方法,获取单例指针
    static Printer*getSignlePrint(void)
    {
        return signlePrint;
    }
private:
    //3.防止 该类实例化其他对象 将构造函数全部私有
    Printer();
    ~Printer();
public:
  //功能函数
    void printText(char*str){
    cout<<"打印"<<str<<endl;
    }

}
Printer *Printer::signlePrint=new Printer;

调用:
Printer*p1=Printer::getSignlePrint();
p1->printText("你好");

6. 将QList<QStringList>转换为std::vector<std::vector<std::string>>  

         QList<QStringList> rows;
         QStringList row1;
         row1 << "New"
              << "Row"
              << "Data";
        rows.append(row1);
        QStringList row2;
        row2 << "New2"
             << "Row2"
             << "Data2";
        rows.append(row2);
// 将QList<QStringList>转换为std::vector<std::vector<std::string>>
        std::vector<std::vector<std::string>> rows_str;
        for (auto& row : rows) {
            std::vector<std::string> row_str;
            for (auto& item : row) {
                row_str.push_back(item.toStdString());
            }
            rows_str.push_back(row_str);
        }

7.for循环

特性for (auto row : rows)for (auto& row : rows)
row 的类型值的副本(拷贝)元素的引用
是否影响原始容器不影响会直接影响
适用场景只需要读取值,或对副本操作需要修改容器中的元素
性能开销可能有拷贝开销,尤其是复杂对象无拷贝开销,但需注意避免误修改

实际使用建议

  • 如果只是读取或处理临时值,用 for (auto row : rows)
  • 如果需要修改容器中的元素,用 for (auto& row : rows)
  • 如果不需要修改元素但想避免拷贝开销,可以用 for (const auto& row : rows)
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> rows = {1, 2, 3, 4, 5};

    for (auto row : rows) {  // 值拷贝
        row = row * 2;       // 修改的是副本
    }

    // 输出 rows,检查是否被修改
    for (const auto& r : rows) {
        cout << r << " ";    // 输出: 1 2 3 4 5
    }
    cout << endl;

    return 0;
}

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> rows = {1, 2, 3, 4, 5};

    for (auto& row : rows) {  // 引用
        row = row * 2;        // 修改的是原始值
    }

    // 输出 rows,检查是否被修改
    for (const auto& r : rows) {
        cout << r << " ";    // 输出: 2 4 6 8 10
    }
    cout << endl;

    return 0;
}

基于迭代器的 for 循环

for (auto it = rows.begin(); it != rows.end(); ++it) {

        // 对 *it 进行操作

}

std::vector<int> rows = {1, 2, 3, 4};

for (auto it = rows.begin(); it != rows.end(); ++it)   {

          *it *= 2; // 通过迭代器访问并修改元素

 }

// rows: {2, 4, 6, 8}

 map

//基于 C++17 的结构化绑定(Structured Bindings)的范围 for 循环
for (const auto& [key, value] : map) {
    // key 是键, value 是值
}
//解释:

//C++17 引入了结构化绑定,允许直接解构类似 std::pair 或 std::tuple 这样的复合类型。
//这种写法常用于遍历 std::map 或其他包含键值对的容器。
//const auto& [key, value] 表示解构出每个元素的键和值,并通过引用访问它们。
//使用场景:

//遍历键值对容器(如 std::map 或 std::unordered_map)
std::map<int, std::string> my_map = {{1, "one"}, {2, "two"}};
for (const auto& [key, value] : my_map) {
    std::cout << "Key: " << key << ", Value: " << value << std::endl;
}
// 输出:
// Key: 1, Value: one
// Key: 2, Value: two

for (const auto& mayt : mymap) {
	cout << mayt.first << " ";
	cout << mayt.second << endl;
}
// 遍历map
for (std::map<int, std::string>::iterator it = mymap.begin(); it != mymap.end(); ++it) {
		std::cout << it->first << ": " << it->second << std::endl;
}
for (auto it = mymap.begin(); it != mymap.end(); ++it) {
		std::cout << it->first << ": " << it->second << std::endl;
}

for (auto it = level_left_date.cbegin(); it != level_left_date.cend(); ++it) {
    qDebug() << "Key:" << it.key() << ", Value:" << it.value();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想要入门的程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值