首页 > 编程语言 >C++学习---qt的公有类、私有类、Q_Q、Q_D、二进制兼容

C++学习---qt的公有类、私有类、Q_Q、Q_D、二进制兼容

时间:2023-06-28 16:14:02浏览次数:45  
标签:const qt 私有 return C++ Class --- MyClass ptr

1、二进制兼容

如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的。

如果不能保证库的二进制兼容性,就意味着每次发布库的新版本时,依赖该库的所有程序都必须重新编译才能正常运行。

2、公有类、私有类

是解决信息隐藏的问题的,发布库文件时只提供公有类的头文件而不必提供私有类的头文件,从而隐藏掉一些不想公开的内容。

如果修改的内容是私有类里面的,那么重新编译库以后,对外的公有类并没有发生变化,从而达到二进制兼容的目的。

因此这样设计类的目的至少有两个:

(1)信息隐藏

(2)二进制兼容

你不应该把这样的 private class 放在你的类的同一个头文件中,因为这样做的话就没有意义了。常见做法是,定义一个 private 的头文件,例如使用 myclass_p.h 的命名方式(这也是 Qt 的命名方式)。并且记住,不要把 private 头文件放到你发布的 include 下面!因为这不是你发布的一部分,它们是私有的。

或者把私有类定义在公有类的cpp文件中。

一般是将公有类中的private成员放在私有类中。

3、Q_Q、Q_D

Q_Q是私有类访问公有类的方法。

Q_D是公有类访问私有类的方法。

template <typename T> inline T *qGetPtrHelper(T *ptr) { return ptr; }
template <typename Ptr> inline auto qGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
 
#define Q_DECLARE_PRIVATE(Class) \
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
    friend class Class##Private;
 
#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr)); } \
    friend class Class##Private;
 
#define Q_DECLARE_PUBLIC(Class)                                    \
    inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
    inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \
    friend class Class;
 
#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()

以上设计也称为d-pointer,“d-pointer” 这个名字源于 Trolltech 公司的 Arnt Gulbrandsen,他首先将这项技术引入到 Qt 中,使其成为第一个在大版本之间保持二进制兼容性的 C ++ GUI 库之一。 所有看过它的人都很快将这种技术作为 KDE 库的一般编程模式。这是能够在不破坏二进制兼容性的情况下将新的私有数据成员添加到类中是一个很好的技巧。

 

一个简单的公有类、私有类设计例子为:

myclass.h

// myclass.h  
#ifndef MYCLASS_H  
#define MYCLASS_H  
#include <QtCore/QObject>  
class MyClassPrivate;  
class MyClass: public QObject  
{  
  Q_OBJECT  
public:  
  MyClass(QObject *parent = 0);  
  virtual ~MyClass();  
  void dummyFunc();  
signal:  
  void dummySignal();  
private:  
  MyClassPrivate * const d_ptr;  
  Q_DECLARE_PRIVATE(MyClass);  
  Q_DISABLE_COPY(MyClass);  
};  
#endif // MYCLASS_H  

myclass.cpp  

// myclass.cpp  
#include "myclass.h"  
class MyClassPrivate  
{  
public:  
  MyClassPrivate(MyClass *parent)  
    : q_ptr(parent)  
  {  
  }  
  void foobar()  
  {  
    Q_Q(MyClass);  
    emit q->dummySignal();  
  }  
private:  
  MyClass * const q_ptr;  
  Q_DECLARE_PUBLIC(MyClass);  
};  
MyClass::MyClass(QObject *parent)  
  : QObject(parent)  
  , d_ptr(new MyClassPrivate(this))  
{  
}  
MyClass::~MyClass()  
{  
  Q_D(MyClass);  
  delete d;  
}  
void MyClass::dummyFunc()  
{  
  Q_D(MyClass);  
  d->foobar();  
}

 

标签:const,qt,私有,return,C++,Class,---,MyClass,ptr
From: https://www.cnblogs.com/zzzsj/p/17511693.html

相关文章

  • JavaScript-常用字符串方法和属性
    JavaScript-常用字符串方法和属性charAt()//返回指定位置处的字符。charCodeAt()//返回指定位置处字符编码。codePointAt()//返回字符串中索引(位置)处的Unicode值。concat()//返回两个或多个连接的字符串。constructor返回字符串的构造函数。endsWith()//返回......
  • 【Oracle】使用PL/SQL快速查询出1-9数字
    【Oracle】使用PL/SQL快速查询出1-9数字简单来说,直接RecursiveWITHClauses在Oracle里面就直接使用WITHresult(参数)即可WITHresult(num)AS(SELECT1ASnumfromdualUNIONALLSELECTnum+1ASnumFROMresultWHEREnum<9)SELECTnumFROMresult......
  • C++ 相关系数的计算以及作用
    #include<iostream>#include<vector>#include<cmath>usingnamespacestd;//计算平均值doublemean(vector<double>v){doublesum=0;for(inti=0;i<v.size();i++){sum+=v[i];}returnsum/v.si......
  • 3-IO对象
    1-常用对象名称作用属性及参数Text(str)显示文本strInput()用户输入Button(name)按钮2-实例应用importPySimpleGUIassgsg.theme('GrayGrayGray')layout=[[sg.Text('Youarewelcome!')],[sg.Text('name:'),sg.Input()],......
  • curl -I 192.168.74.128 拒绝连接
     查看直接的linuxweb服务器信息 curlwww.baidu.com都是正常的,唯独curl本机的ip地址就一直报错 由于使用的yum安装的nginx,nginx的一些模块依赖一些lib库,所以在安装nginx,也必须先安装这些lib库,这些依赖库主要有g++、gcc、openssl-devel、pcre-devel和zlib-devel所以执......
  • 博士论文写作-引言
      引论也叫绪论,或称引言、前言、概述、导论等,是论文的开场白。古代文论中有“凤头、猪肚、豹尾”之称,可见其重要。虽然学术论文不强调开头像凤头那样俊美、精采、引人入胜,但引论是给读者的第一印象,对全文有提纲挈领的作用,也不可等闲视之。引论作为论文的前置部分,是提出论点......
  • ionic3安卓触发返回键ion-datetime不自动关闭
    框架:ionic3+angular机型:安卓问题:点击打开ion-datetime选择框,直接使用物理返回键(或自带的滑动返回)时,页面返回上一页但ion-datetime弹窗仍未关闭。理想情况:返回时会自动关闭ion-datetime弹窗再返回上一页解决方法://page.tsimport{Platform}from'ionic-angular';.........
  • Linux - 操作mysql数据库
    运行环境Ubuntu20.04虚拟机Mysql8.0APIlibmysqlclient-devgcc9.4.0一、准备工作1、在Ubuntu上准备mysql开发环境更新软件源sudoaptupdate安装libmysqlclient-dev,这个lib库是Linux下C/C++连接mysql的客户端sudoaptinstalllibmysqlclient-dev2、创建测试数据库......
  • 创建模式-抽象工厂
    #创建型模式-抽象工厂模式#在工厂抽象类中有多个创建对象的方法,fromabcimportABCMeta,abstractmethodclassIApple(metaclass=ABCMeta):@abstractmethoddefshow(self):passclassHFSApple(IApple):defshow(self):print("红......
  • Python - Ridiculous Rounding
     Python3uses“Banker’sRounding”whichisdefinedlikethis:“Exacthalfwaycasesarenowroundedtothenearestevenresultinsteadofawayfromzero”-perWhat’snewinPython3.Inthecaseof1.5,Pythonroundstotwobecausethatisthenear......