IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 记录一些C++用法 -> 正文阅读

[C++知识库]记录一些C++用法

访问空指针程序崩溃的底层剖析

转化运算符

const_cast转换符是用来移除变量的const或volatile限定符。
const_cast转换运算符用来去除变量的底层const属性,这里的变量的类型是指针或者引用类型,因为普通类型并没有底层const属性这个说法。
c++ const_cast转换运算符与volatile关键字

断言

运行时断言:assert
静态断言:C++11静态断言 static_assert(断言表达式必须是常量表达式)
static_assert是编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。

赋值运算符、拷贝构造、右值

const T&与T const&等

友元

被声明为友元的函数或者类B,则可以访问当前类A的私有接口和变量(通俗解释就是,B是A的好朋友,那么B就可以去访问好朋友A的私有数据,或者A就愿意公开自己的私有数据给好朋友B)。
友元函数:在定义一个类的时候,可以把一些函数(包括全局函数和其他类的成员函数)声明为“友元(把friend标志置于函数声明的最前),这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对象的私有成员了。

class CCar
{
private:
    int price;
    // 声明友元,该函数内部可以使用cars[i]对象直接访问price私有成员变量
    friend int MostExpensiveCar(CCar cars[], int total);  
    friend void CDriver::ModifyCar(CCar* pCar);  // 声明友元
};

友元类:一个类 A 可以将另一个类 B 声明为自己的友元,类 B 的所有成员函数就都可以访问类 A 对象的私有成员。在类定义中声明友元类的写法如下:friend class 类名;

class CCar
{
private:
    int price;
    friend class CDriver;  //声明 CDriver 为友元类,那么CCar的私有变量price就让CDriver类访问到
};
class CDriver
{
public:
    CCar myCar;
    void ModifyCar()  //改装汽车
    {
        myCar.price += 1000;  //因CDriver是CCar的友元类,故此处可以访问其私有成员
    }
};

如何访问类的私有成员

  • 提供公共接口,返回私有成员(间接访问)
  • 友元

Resource Acquisition Is Initialisation (RAII)

RAII是一种使用在面向对象语言中的资源(内存,互斥锁,或者文件描述符)管理机制
意味着任何资源的获取都应该发生在类的构造函数中,资源的释放应发生在析构函数中。

头文件少用前置声明

头文件的前置声明:

class InspectorEventModel;
class EventTermModel;
class EventNodeModel;
class EventModelBase;
class ResultTermModel;
class ConditionTermModel;
class InspectorEvent : public InspectorBase

容易出现编译问题。
在如下的调用中,总提示m_inspectorEvent->GetInspectorEventModel()处有对QVariant的错误。主要是调用setContextProperty接口时,调用到了void setContextProperty(const QString &, const QVariant &);这个,而不是void setContextProperty(const QString &, QObject *);,而QVariant是不允许传递VOID *指针进去的。因为inline QVariant(void *) = delete; QVariant把对于传入VOID *指针的构造声明为了delete
而此时,另外一个相同的代码,确可以成功编译,然后点进去setContextProperty对于它的调用,确是走入了void setContextProperty(const QString &, QObject *);,说明成功编译的代码,此处GetInspectorEventModel返回的值被识别为了一个正常的QObject指针类型(或者说是其相关的子类类型),而编译失败的返回的值被识别为了一个VOID *,这里可以大致猜想到,CPP文件没法识别返回值,而转为了VOID *。此时就往GetInspectorEventModel返回的值是否添加了头文件识别上去查。
果然,因为GetInspectorEventModel的头文件中对于该返回值做了前置声明,而它的实现的CPP文件内,没有对这个返回值添加头文件引用,导致无法识别这个类型!!!!

    engine()->rootContext()->setContextProperty("inspectorEventModel",
                                                m_inspectorEvent->GetInspectorEventModel());
                                               
// m_inspectorEvent->GetInspectorEventModel()的定义                                               
InspectorEventModel *InspectorEvent::GetInspectorEventModel() const
{
    return static_cast<InspectorEventModel *>(m_inspectorModel.get());
}

使用typedef定义别名

在类中定义,让这个别名归属于此类的范畴中。

class AtomCommand
{
public:
    typedef std::shared_ptr<AtomCommand> ptr;
    typedef QVector<ptr> ptrVec;

友元

new 和 make_shared的区别

内存上:先new然后赋值的方式,会导致内存碎片化
make_shared的方法分配内存,不会导致内存产生过多的碎片

   A* a = new A;										//①
   std::shared_ptr<A> pa(a);

   std::shared_ptr<A> pa1 = std::make_shared<A>(1);              //②

通过①的方式,是先在堆上分配一块内存,然后在堆上再建一个智能指针控制块,这两个东西是不连续的,会造成内存碎片化
通过②的方式,是直接在堆上新建一块足够大的内存,其中包含两部分,上面是内存(用来使用),下面是控制块(包含引用计数),然后用A的构造函数去初始化分配的内存(分配一块内存的步骤:先分配内存,再进分配的内存调用构造函数进行构造,构造完毕才能使用)
Std::shared_ptr管理两个实体:

智能指针

virtual函数中默认参数的表现

结论:小心使用。使用时也要保持基类和子类的默认参数一致!不一致的情况下会有可能引发问题。
即虚函数,执行那个函数是运行时决定的,但是其默认参数却是静态决定的,用了什么类型的指针就使用哪套默认参数。
参考:Effective C++ .37 virtual函数中默认参数的表现
子类成员函数需要定义一个默认参数,那么基类的成员函数一定需要定义一个默认的参数。
基类定义的成员函数,需要附带默认参数。

    virtual inline void SetDisplayName(const std::string &name = "")
    {
        m_displayName = name;
    }

定义ModelPrivate

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:06:35  更:2022-11-05 00:09:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 6:20:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码