定义Human类
human.h文件
#ifndef HUMAN_H
#define HUMAN_H
#include <QObject>
#include <QtGlobal>
#include <QDate>
//
/**
*【一】二进制兼容 前提条件
*1.C++空对象占1个字节,而不是0个字节;
*2.类中的成员函数是不占用类对象的内存空间的;
*3.非静态成员变量是占用对象的内容空间,同时会进行字节对齐;
*4.静态成员变量是跟着类走的,所有类对象公用它,和成员函数一样,所以是不占用对象内存空间的;
*5.如果类中有一个或多个虚函数时,则对象内存空间会增加4个字节(32位系统下)用来存放虚函数表指针(virtual table pointer);
*【二】会破坏二进制兼容的操作
*1.添加新的虚函数
*2.改变类的继承
*3.改变虚函数声明时的顺序
*4.添加新的非静态成员变量
*5.改变非静态成员变量的声明顺序
*【三】不会破坏二进制兼容的常见操作有
*1.添加非虚的成员函数
*2.添加新的类 添加Qt中的信号槽
*3.在已存在的枚举类型中添加一个枚举值
*4.添加新的静态成员变量
*5.修改成员变量名称(偏移量未改变,但是可能会破坏源码兼容!更严重..)
*6.添加Q_OBJECT,Q_PROPERTY, Q_ENUMS ,Q_FLAGS宏,添加这些宏都是修改了moc生成的文件,而不是类本身
*/
class HumanPrivate;
class Human:public QObject
{
Q_OBJECT
public:
Human(QObject* parent);
QDate Birthday();
QDate Deathday();
public slots:
void setBorn(const QDate&);
void setDied(const QDate&);
signals:
void NotifyDied(const QDate&);
void NotifyBorn(const QDate&);
protected:
HumanPrivate* const d_ptr;
private:
Q_DECLARE_PRIVATE(Human);// 相关定义声明明确 d_func() ;注意参数是当前类名,是Human
Q_PRIVATE_SLOT(d_func(),void setBirthday(const QDate &))// 私有类(HumanPrivate)中的槽函数 映射到Human中
Q_PRIVATE_SLOT(d_func(),void setBirthday(const QDate &))// 同上
Q_PRIVATE_SLOT(d_func(),void privateSlotPrintName())// 同上
Q_DISABLE_COPY(Human);// 删除拷贝构造和赋值构造
Q_DISABLE_MOVE(Human);// 删除移动构造和移动赋值 (c++11新特性,右值概念、std::move这些东西)
};
class Male:public Human
{
public:
using Human::Human;
};
class Female:public Human
{
public:
using Human::Human;
};
#endif // HUMAN_H
human.cpp文件
#include "human.h"
#include <QDebug>
class HumanPrivate
{
public:
HumanPrivate(Human *parent): q_ptr(parent) {}
QDate getBirthday() const;
void setBirthday(const QDate &newBirthday);
QDate getDeathday() const;
void setDeathday(const QDate &newDeathday);
private:
void privateSlotPrintName(){
qDebug()<<__func__<<"\tbirthday:"<<birthday<<"\tdeathday:"<<deathday;
}
QDate birthday;
QDate deathday;
private:
Human * q_ptr;
Q_DECLARE_PUBLIC(Human);// 注意参数是Human
};
QDate HumanPrivate::getBirthday() const
{
return birthday;
}
void HumanPrivate::setBirthday(const QDate &newBirthday)
{
Q_Q(Human);// 可以获取到q指针
birthday = newBirthday;
emit q->NotifyBorn(birthday);
}
QDate HumanPrivate::getDeathday() const
{
return deathday;
}
void HumanPrivate::setDeathday(const QDate &newDeathday)
{
Q_Q(Human);
deathday = newDeathday;
emit q->NotifyDied(deathday);
}
Human::Human(QObject* parent):QObject(parent),d_ptr(new HumanPrivate(this))
{
connect(this,SIGNAL(NotifyBorn(QDate)),this,SLOT(privateSlotPrintName()));
connect(this,SIGNAL(NotifyDied(QDate)),this,SLOT(privateSlotPrintName()));
}
void Human::setBorn(const QDate &date)
{
Q_D(Human);// 获取到d指针
//d_ptr->setBirthday(date);
d->setBirthday(date);
}
void Human::setDied(const QDate &date)
{
d_ptr->setDeathday(date);
}
#include "moc_human.cpp" //注意要加这个include
main.cpp
#include <QApplication>
#include "human.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Human human(nullptr);
human.setBorn(QDate(1998,2,2));
human.setDied(QDate::currentDate());
return a.exec();
}
输出
privateSlotPrintName birthday: QDate(“1998-02-02”) deathday: QDate(Invalid)
privateSlotPrintName birthday: QDate(“1998-02-02”) deathday: QDate(“2024-04-26”)