由使用两种方法创建对象引发的思考

来源:互联网 发布:mac怎么退出u盘 编辑:程序博客网 时间:2024/05/15 00:37

一、首先创建对象的方法有两种:

  1. QPushButton *pushButton= new QPushButton (this);
  2. QPushButton pushButton;

区别在于存储空间上不同,new出来的在堆上,第二种直接定义的在栈上。
对于高手而言都喜欢用new,因为堆的存储大,可以用到很多的动态重载性。
二、栈上分配的内存函数结束时候会自己释放,堆上的要自己手工释放。使用new的其它好处:
1、需要的时候才new(在复杂权限和业务逻辑系统中很重要)
2、对象可靠性检查(没有栈空间的限制问题)
3、对象的适度留用控制
三、new的作用:首先就要从C++的语法去解释了
1、new是一个操作符 。new的过程:当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:
获得一块内存空间、调用构造函数、返回正确的指针。
当然,如果我们创建的是简单类型的变量,那么第二步会被省略。定义了如下一个类Test:
class Test
{
int i;
public:
Test(int _i) ;
};
// 调用new:
Test* pa = new Test(3);
那么上述动态创建一个对象的过程大致相当于以下三句话(只是大致上):
Test* pa = (A*)malloc(sizeof(Test));
pa->Test::Test(3);
return pa;
虽然从效果上看,这三句话也得到了一个有效的指向堆上的Test对象的指针pa,但区别在于,当malloc失败时,它不会调用分配内存失败处理程序new_handler,而使用new的话会的。
另外:Qt窗体上的子窗体一般是“new”创建的,当父窗体删除的时候,同时也会清理相关的子窗体;
如果子窗体不是“new”创建的,而是用static变量创建,关闭父窗体的时候会程序崩溃,原因应该是父窗体删除到static子窗体时不对;
//这样会导致问题;
// static NewQWidget1 nqwt(this);
// nqwt.show();

//一般创建方法:
NewQWidget1 * pNewQWidget1 = new NewQWidget1(this);
pNewQWidget1->show();

四、this的作用?
首先使用Qt Creator创建一个默认的widget窗体
//头文件

#ifndef WIDGET_H#define WIDGET_H#include <QWidget>class Widget : public QWidget{    Q_OBJECTpublic:    Widget(QWidget *parent = 0);    ~Widget();};#endif // WIDGET_H

.cpp文件

#include "widget.h"Widget::Widget(QWidget *parent)    : QWidget(parent){}Widget::~Widget(){}

mian.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    Widget w;    w.show();    return a.exec();}

上面是默认创建的三个文件。
在头文件中 Widget(QWidget *parent = 0);
与在.cpp文件中 Widget::Widget(QWidget *parent): QWidget(parent)
的关系是上面?先看子窗体的显示方式
二:子窗口设置方式:

(1):通常情况下,对于一个继承与QWidget的子窗体,直接 new NewQWidget1(this);(或setparent(this)) 参数设置为父窗体,然后 show(),这样就可以在指定窗口上创建子窗口;
(2):如果 一个窗口继承与QDialog,用这种方法,
NewQWidget1 * pNewQWidget1 = new NewQWidget1(this);
pNewQWidget1->show();
只是创建了一个非模态对话框,如果想要这个飞模态对话框显示到指定窗口上,解决方法:
设置这个窗口的属性:
(1):pNewQWidget1->setWindowFlags(Qt::Widget); //直接设置QDialog为QWidget;
pNewQWidget1->show(); //设置后重新显示;
(2):
pNewQWidget1->setWindowFlags(Qt::SubWindow); //设置QDialog为子窗口属性;
pNewQWidget1->show(); //设置后重新显示;
(3):
pNewQWidget1->setWindowFlags(Qt::CustomizeWindowHint|Qt::FramelessWindowHint);//设置自定义无边框窗口;
pNewQWidget1->show(); //设置后重新显示;
以上简单列举三种方法,但是可以根据具体需求设置;

在回到关系的话题上:
关系是重定义父对象。如何重定义呢?看parent参数。
当Widget 放到某个窗口上的时候,该Widget 的父对象就被重定义为该窗口。
但是,由于Widget 本身继承于QWidget,那么还需要对QWidget的父对象重定义。Widget 通过parent指针来告诉父类QWidget:“我的父对象是该窗口,请通过你的构造函数来实现这个目的”。
注意:父类与父对象的区别。
父对象是对父类的实例化,父对象是为了内存管理而出现的,如果一个对象的父对象销毁了,那么这个对象也自动销毁,释放内存

回到this上:this指针在类的非静态成员函数里面才能使用,main函数里是不能使用的!

关于this指针的一个经典回答:
当你进入一个房子后,   
你可以看见桌子、椅子、地板等,   
但是房子你是看不到全貌了。   
对于一个类的实例来说,   
你可以看到它的成员函数、成员变量,   
但是实例本身呢?   
this是一个指针,它时时刻刻指向你这个实例本身

(1)this只能在成员函数中使用。
全局函数、静态函数都不能使用this.
由此可见,this在成员函数的开始前构造,在成员函数的结束后清除。
(2)这个生命周期同任何一个函数的参数是一样的,没有任何区别。
(3) this指针存放位置会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量。

综上:
QPushButton *pushButton= new QPushButton (this);中如果不加入this就无法显示button。
原因就是QPushButton 是继承与QWidget的子窗体。建立的窗体是Widge使用this指向自己就能显示了。

最后补充在建立widget是会有关键字explicit; 例如 explicit Widget(QWidget *parent = 0);
explicit 英文直译是“明确的”、“显式的”意思。出现这个关键字的原因,是在C++中有这样规定的基础上: 当定义了只有一个参数的构造函数时,同时也定义了一种隐式的类型转换
explicit 可以禁止“单参数构造函数”被用于自动类型转换

0 0
原创粉丝点击