当前位置: 首页 > wzjs >正文

电商网站设计是什么虚拟服务器和如何创建网站

电商网站设计是什么,虚拟服务器和如何创建网站,90后做网站,室内设计平面图讲解目录 前置知识: (1)C运行时多态 (2)RTTI QT的元对象系统 1.元对象系统基本内容 2.元对象代码 3.元对象系统其它特性 前置知识: (1)C运行时多态 C的运行时多态是由虚函数和继…

目录

前置知识:

(1)C++运行时多态

(2)RTTI

QT的元对象系统

1.元对象系统基本内容

2.元对象代码

3.元对象系统其它特性


前置知识:

(1)C++运行时多态

C++的运行时多态是由虚函数和继承实现的。当一个基类中存在虚函数的时候,基类指针就可以指向任何派生类的对象。如果在基类中声明了虚函数,并在派生类中重写了这些虚函数,当基类指针或引用指向派生类对象并调用虚函数时,会根据对象的实际类型而不是指针类型来确定调用的函数。

例如,下面这段程序,main函数中,父类指针指向派生类对象。父类Parent中的come被声明为虚函数,在main函数中,虽然指向两个派生类对象的是父类指针,但是运行时还是调用派生类中的come()函数。

#include <iostream>using namespace std;class Parent
{
public:Parent() {cout << "我是你父母" << endl;}virtual ~Parent() {cout << "父类析构" << endl;}virtual void come(){cout << "父母来了" << endl;}
};class Son : public Parent
{
public:Son() {cout << "我是你儿子" << endl;}~Son() override {cout << "儿子析构" << endl;}void come(){cout << "儿子来了" << endl;}
};class Daughtor : public Parent
{
public:Daughtor() {cout << "我是你闺女" << endl;}~Daughtor() override {cout << "闺女析构" << endl;}void come(){cout << "闺女来了" << endl;}
};int main()
{Parent *child1 = new Son();Parent *child2 = new Daughtor();child1->come();child2->come();delete child1;delete child2;return 0;
}

输出:

但是如何判断基类指针到底指向的那个对象呢?这就用到了RTTI机制。

(2)RTTI

RTTI(Run-Time Type Identification)是C++中的一种机制,允许在运行时确定对象的类型。程序能够使用基类的指针或引用,来检查这些指针或引用所指的对象的实际派生类型。 

RTTI提供了两个非常有用的操作符:dynamic_cast和typeid。

(2.1)dynamic_cast

dynamic_cast(expression):dynamic_cast 主要用于在继承体系中进行安全的向下转换(基类指针或引用------->派生类指针或引用)。dynamic_cast 是一种安全的转换,有类型检查的功能,如果转换失败返回NULL。

因此,dynamic_cast可以用来判断父类对象是否存在某个派生类,如以下程序所示:Son继承了Parent,是Parent的派生类;daughtor没有继承Parent,不是Parent的派生类。使用dynamic_cast将p转为Daughtor类型时返回NULL。

#include <iostream>using namespace std;class Parent
{
public:Parent() {cout << "我是你父母" << endl;}virtual ~Parent() {cout << "父类析构" << endl;}virtual void come(){cout << "父母来了" << endl;}
};class Son : public Parent
{
public:Son() {cout << "我是你儿子" << endl;}~Son() override {cout << "儿子析构" << endl;}void come(){cout << "儿子来了" << endl;}
};class Daughtor 
{
public:Daughtor() {cout << "我是你闺女" << endl;}~Daughtor()  {cout << "闺女析构" << endl;}void come(){cout << "闺女来了" << endl;}
};int main()
{Parent *p = new Son();Son *son = dynamic_cast< Son *> (p);if(son != nullptr){cout << "p有son子类" << endl;}else{cout << "p没有son子类" << endl;}Daughtor *daughtor = dynamic_cast< Daughtor *> (p);if(daughtor != nullptr){cout << "p有daughtor子类" << endl;}else{cout << "p没有daughtor子类" << endl;}delete p;return 0;
}

输出:

(2.2)typeid

typeid能够返回类型的名字,在前面的代码里增加下面的代码,也可以判断指针和所指向对象的类型。

    if(typeid(p).name() ==  typeid(Parent*).name()){cout << "p指针是Parent类型" << endl; }else if(typeid(p).name() ==  typeid(Son*).name()){cout << "p指针是Son类型" << endl; } if(typeid(*p).name() ==  typeid(Parent).name()){cout << "p指针指向的是Parent类型" << endl; }else if(typeid(*p).name() ==  typeid(Son).name()){cout << "p指针指向的是Son类型" << endl; } 

完整代码:

#include <iostream>using namespace std;class Parent
{
public:Parent() {cout << "我是你父母" << endl;}virtual ~Parent() {cout << "父类析构" << endl;}virtual void come(){cout << "父母来了" << endl;}
};class Son : public Parent
{
public:Son() {cout << "我是你儿子" << endl;}~Son() override {cout << "儿子析构" << endl;}void come(){cout << "儿子来了" << endl;}
};class Daughtor 
{
public:Daughtor() {cout << "我是你闺女" << endl;}~Daughtor()  {cout << "闺女析构" << endl;}void come(){cout << "闺女来了" << endl;}
};int main()
{Parent *p = new Son();Son *son = dynamic_cast< Son *> (p);if(son != nullptr){cout << "p有son子类" << endl;}else{cout << "p没有son子类" << endl;}Daughtor *daughtor = dynamic_cast< Daughtor *> (p);if(daughtor != nullptr){cout << "p有daughtor子类" << endl;}else{cout << "p没有daughtor子类" << endl;}if(typeid(p).name() ==  typeid(Parent*).name()){cout << "p指针是Parent类型" << endl; }else if(typeid(p).name() ==  typeid(Son*).name()){cout << "p指针是Son类型" << endl; } if(typeid(*p).name() ==  typeid(Parent).name()){cout << "p指针指向的是Parent类型" << endl; }else if(typeid(*p).name() ==  typeid(Son).name()){cout << "p指针指向的是Son类型" << endl; } delete p;return 0;
}

输出: 

通过前面的代码示例,我们知道,dynamic_cast和typeid能判断是不是某个类型,但是dynamic_cast和typeid也只能判断是不是某个类型,也就是只能知道类型名。这就是C++的缺点所在,也是Qt创建元对象系统的原因之一。

完整的描述一个类型需要很多信息,例如类的名字、有哪些父类、有哪些成员变量、有哪些成员函数、哪些是public的、哪些是private的、哪些是protected的等等。有时候一个工程项目可能包含成千上万个类,完整的保存这些信息将会消耗大量的内存资源。为了节省内存,C++标准约定typeid只能返回类名。因此,仅靠dynamic_cast和typeid两个关键字提供的类型信息实在有限。[1]

由于C++的RTTI机制只能提供有限的类型信息,于是Qt构建了自己的元对象系统(Meta-Object)。使用该系统的基类QObject所创建的派生类对象,可以在运行期获取该对象的类名、父类名、枚举类型以及有哪些成员变量、有哪些成员函数等信息。[1]

QT的元对象系统

1.元对象系统基本内容

Qt中的元对象系统(Meta-Object System)提供了对象间通信的信号和槽机制运行时类型信息动态属性系统QT中的元对象系统基于以下三个方面:

1)QObject类为能够利用元对象系统的类提供了一个基类。

2)" Q_OBJECT"宏用于启用元对象功能,例如信号槽机制。(一般建议在QObject的所有子类中使用Q_OBJECT宏,而不管它们是否使用了信号与槽。)

3)元对象编译器moc( Meta-Object Compiler )为每个QObject子类提供了实现元对象功能所需的代码。

moc工具读取一个c++源文件,如果它发现一个或多个包含Q_OBJECT宏的类声明,它会解析类的结构(信号、槽、属性、枚举等)等,并生成另一个c++源文件moc_*.cpp,其中包含每个类的元对象代码(元对象代码是Qt元对象系统的核心组成部分,它为Qt提供了信号与槽机制、动态属性系统和反射能力。)。生成的源文件要么#include到类的源文件中,要么(更常见的是)编译并链接到类的实现中。moc是由构建系统自动执行的。

2.元对象代码

例如,编写了一个widget.cpp,其中创建了widget类继承自QObject类并包含了Q_OBJECT宏。编译后,moc工具会自动生成一个名为moc_widget.cpp的文件:

1)MOC 生成的元对象数据结构存储类的所有元信息。(每个类只有一个元对象,它包含了类的名称、父类指针、属性、信号和槽等信息[4]。)

2)信号在 MOC 生成的代码中被实现为调用QMetaObject::activate():

3)每个槽函数对应一个元方法索引,用于运行时调用:

4)每个类的元对象通过staticMetaObject访问:

3.元对象系统其它特性

元对象系统主要是为了实现信号和槽机制才被引入的,不过除了信号和槽机制以外,元对象系统还提供了其他一些特性:

  • QObjeCt::metaObject()函数可以返回一个类的元对象,它是QMetaObject类的对象;
  • QMetaObject::className()可以在运行时以字符串形式返回类名,而不需要C+ +编辑器原生的运行时类型信息(RTTI)的支持;
  • QObject:: “inherits()函数返回一个对象是否是QObject继承树上一个类的实例的信息;
  • QObject: :tr()和QObject: :trUtf8()迸行字符串翻译来实现国际化;
  • QObject::setProperty()和QObject::property()通过名字来动态设置或者获取对象属性;
  • QMetaObject: :newlnstance()构造该类的一个新实例。

1)QObjeCt::metaObject()函数可以返回一个类的元对象,它是QMetaObject类的对象;

MyClass obj;
const QMetaObject* metaObj = obj.metaObject();

2) QMetaObject::className()可以在运行时以字符串形式返回类名,而不需要C+ +编辑器原生的运行时类型信息(RTTI)的支持;

// 获取类名
qDebug() << "类名:" << metaObj->className(); // 输出: "MyClass"

3)QObject:: “inherits()函数返回一个对象是否是QObject继承树上一个类的实例的信息;

#include <QObject>
#include <QWidget>
#include <QPushButton>
#include <QDebug>void printObjectHierarchy (const QObject* obj) {
qDebug () << "对象类型:" << obj->metaObject ()->className ();qDebug () << "是否是 QObject:" << obj->inherits ("QObject");
qDebug () << "是否是 QWidget:" << obj->inherits ("QWidget");
qDebug () << "是否是 QPushButton:" << obj->inherits ("QPushButton");
qDebug () << "是否是 QLabel:" << obj->inherits ("QLabel");
}int main() {
QObject baseObj;
QWidget widget;
QPushButton button;qDebug () << "=== QObject 对象 ===";
printObjectHierarchy (&baseObj);qDebug () << "\n=== QWidget 对象 ===";
printObjectHierarchy (&widget);qDebug () << "\n=== QPushButton 对象 ===";
printObjectHierarchy (&button);return 0;
}

4)QObject: :tr()和QObject: :trUtf8()迸行字符串翻译来实现国际化;

5)QObject::setProperty()和QObject::property()通过名字来动态设置或者获取对象属性;

​使用通用函数QObject::property() 和QObject::setProperty() 可以读写属性,除了属性名称外,无需知道属性所属类的任何信息。在下面的代码片段中,调用QAbstractButton::setDown() 和调用QObject::setProperty() 都设置了属性 "down"。 ​

QPushButton *button = new QPushButton;
QObject *object = button;button->setDown(true);
object->setProperty("down", true);

其他关于属性的详细内容可查看Qt官方手册: 

The Property System | Qt Core | Qt 6.9.0

6)QMetaObject: :newlnstance()构造该类的一个新实例。

当通过类型名构造类的新实例时,必须知道类型名。而newInstance()可以在运行时动态创建对象。

// 编译时已知类型创建实例
MyClass* obj = new MyClass(parent);
// 运行时通过元对象创建实例
const QMetaObject* metaObj = &MyClass::staticMetaObject;
QObject* obj = metaObj->newInstance(Q_ARG(QObject*, parent));

详细示例可查看下面的博客: 

使用Qt的meta-object系统,如QMetaObject::newInstance,QMetaObject::invokeMethod等创建对象 - 不败剑坤 - 博客园

参考文献:

[1] Qt中的元对象系统(Meta-Object System) - 知乎

[2] C++ typeid关键字详解-CSDN博客

[3] Qt对象模型之二:对象树与元对象系统 - fengMisaka - 博客园

[4] QT 元对象系统实现原理 - 知乎

[5]QMetaObject::newInstance()的使用 - 知乎

[6]使用Qt的meta-object系统,如QMetaObject::newInstance,QMetaObject::invokeMethod等创建对象 - 不败剑坤 - 博客园

http://www.dtcms.com/wzjs/555632.html

相关文章:

  • 怎么在网上卖东西教程广州seo网站推广顾问
  • 微网站建设图片河南高端网站建设公司
  • 如何用vs2010做网站广告赚钱
  • 哪个网站有学做吃的wordpress点击才弹窗插件
  • 山东省建设局网站监理员考试山西太原做网站
  • c 做网站开发加强对网站建设
  • 起名字2023免费八字起名网站关键词优化到首页难度
  • 网站推广策划方案大数据精准获客网址域名大全
  • 赣州网站建设怎么样最新新闻热点事件素材
  • 网站搭建dns有用吗wordpress 路由定义
  • 哪个不是网站开发工具中国神鹰网站建设
  • 深圳网页网站设计网站建设职位要求
  • seo 新旧网站 两个域名东莞网店网页设计公司
  • 浙江网站设计公司微博推广方案
  • 上海防伪网站建设班级网站建设感想
  • 淮安市网站电商网红排行榜
  • 网站建设客户开发方案阿里巴巴国际站运营培训
  • 在哪个网站可以学做衣服黄山旅游最佳时间
  • 手机网站设计教育类模板宿迁房价2023年最新房价
  • 重庆网站制作技术中石化两学一做网站
  • iis网站数据库失败如何建网站教程
  • 又好又快自助建站wordpress发文章功能不能正常显示
  • 做网站优化的注意事项信誉好的做pc端网站
  • 上海找做网站公司哪家好用什么建网站
  • 泰达建设集团网站wordpress手机号
  • 苗木网站素材手表回收网网站
  • 效果图网站推荐大全2021年企业所得税税收优惠政策
  • 网站的标签怎么修改北京核子华曦检测所
  • 高端母婴网站模板短视频矩阵seo系统源码
  • 公司网站建设有哪些公司可以做wordpress设计博客都澜