Qt和C++笔记

QT调试快捷键:

ctrl + r 运行

F5 断点调试,切换断点

F10 进入下一行

F11 进入函数内部

shift + F11 跳出函数

Qtxml相关:

DOM:提供一个接口来访问和改变xml文件中的内容,xml就像是一个有层次的树形视图,可以方便的对xml进行增删改查

SAX:基于事件的标准接口,适用于不需要对文档进行操作,只需要读取整个xml文档

g_root = g_doc.documentElement(); 获取全部的一级目录

QDomNodeList currencyNodes = element.childNodes(); 获取全部的二级目录

QDomNodeList child = apiNodes.at(0).childNodes(); 获取全部的三级目录

XML:可扩展性标记语言

传输和存储数据,不是展示数据。

xml标签自定义,写标签名的要有含义。

<root> 根节点

<user>

标签自定义

</user>

</root>

xml标签区分大小写,不可以交叉;

属性就是表示标签以外的额外信息,比较鸡肋

xml和HTML的区别:

xml标签成对出现,HTML要求不严格

xml用于存储和传输,HTML用于展示

xml标签自定义,HTML不行

xml头声明:<?xml version=1.0 encoding="utf-8" ?>

C++笔记进阶篇:

虚函数和纯虚函数

虚函数是为了实现多态,所谓多态就是一个接口有多种实现的方法,多态实现基类必须要有虚函数,子类对虚函数重写,当然也可以不重写,但是纯虚函数必须重写,实现多态就是基类的指针指向子类的对象,从而可以实现对子类的调用

纯虚函数和虚函数差不多,在基类中不可以实现,只能声明,子类中重写,实现多态。

纯虚函数 virtual void fun()=0; 虚函数 virtual void fun()

虚析构:在父类析构函数前加virtual关键字,当delete父类指针指向的对象时就会释放子类的析构函数。

纯虚析构和虚析构的区别:纯虚析构必须类内声明加virtual,类外实现,Base::~Base(){};

深浅拷贝

类的深浅拷贝,当类中有指针成员时,当旧对象给新对象初始化就会调用拷贝构造函数,Data ca1(10); Data ca2 = ca1;

调用的拷贝构造函数形式为:Data(const Data &ob){ma = ob.ma; cout<<"拷贝构造函数"}

当类中成员含有指针成员时,需要给对象申请独立的地址空间,Data(const Data &ob){name = new char[strlen(ob.name)+1];strcpy(name,ob.name);cout<<"堆区的拷贝构造函数"}

结构体深浅拷贝:浅拷贝:当结构体成员无指针成员时使用,如果含有指针成员,会存在多次释放的问题

深拷贝:当结构体中含有指针成员时,要申请独立的地址空间,实现strcpy后,单独释放

构造函数和析构函数

构造函数和析构函数:构造函数是将对象初始化,可以有参无参,不能有返回值。析构函数将对象清理,有参和无参类型,自动调用

当一个类中含有另一个类名的成员时,会先初始化另一个类的构造函数,再调用自身的构造函数,

先释放自身的析构函数,再释放另一个类的析构函数,class Data{ ob(a); }

类中定义的函数,可以在类外使用ALT+ENTER实现,或者在类外(类名::函数名)实现

重载和重写

重载是在基类中定义相同的方法名,参数不同。重写是基类重写父类的方法,函数名和参数相同。

重载是在一个类中,重写是子类与父类之间

重载是编译时,重写发生在运行时

重载的参数类型,参数个数,参数顺序可以不同,重写子类和父类方法必须相同

重载对返回类型没有要求,重写有要求返回类型

单例模式:

当一个类中含有静态成员时,静态成员是先于所有对象存在的,不需要实例化对象,可以直接通过类名调用,静态成员在类中定义,在类外初始化

普通成员和普通成员函数必须要通过对象调用,一个类中的静态成员和成员函数是被其他所有对象共享的,即一个对象成员发生修改时,其他对象调用时也会改变

class Data{public:static int a;} int Data::a = 100; Data A1; A1.a/Data::a;

只允许该类实例化一个对象,如何实现:将构造函数和析构函数私有化,所以只能在类的内部私有实例化,使用static 类名 * const p;//p保存实例化地址 初始化:类名 *const::p = new 类名(创建唯一的实例)

定义一个公有的静态成员函数,获取实例化地址,static 类名 *getAdress(){}

主函数中使用 类名 *p1 = 类名::静态成员函数;

this指针:当类中的成员变量和成员函数形参重名时,使用this->ma=ma; 非静态成员都默认含有this指针

C++高阶部分

继承

子类继承父类的成员和方法,不能继承构造和析构,重载,赋值运算符

public保持不变,private不可以被继承,protected只能在子类访问,不能在类外访问

格式: class son : public Base

当子类和父类出现同名的成员时,可以使用加作用域区分 (不加优先调用子类)

多继承格式:class son : public Base1,public Base2

C++多态(父类指针指向子类空间)

静态多态,编译时发生(早绑定)【函数重载,运算符重载,重定义】

动态多态,运行时发生(晚绑定)【虚函数】

如果子类和父类出现相同的方法,父类指针指向子类对象时,调用父类的方法。

Base *ob = new Son; ob.func();

所以就要在父类成员函数前加virtual 子类可加可不加,实现多态,也就是

动态绑定机制:当出现virtual关键字,就会生成虚函数指针,虚函数指针查找对应的虚函数表,查找函数的入口地址,如果没有继承,会指向父类的函数入口地址。

如果有继承,子类继承父类的虚函数指针和虚函数表,查找子类的函数入口地址,指向子类的成员函数

重载重写重定义的区别:

  • 重载函数名必须相同,参数列表,返回值类型可以不同。(发生在一个类中)

  • 重写函数名,返回值类型,参数列表都要相同,子类重写父类的虚函数或纯虚函数,多用于多态中。(发生在子类和基类中)

  • 重定义就是子类和父类函数名相同,参数不同,不管有无virtual,都会屏蔽父类函数;参数相同时,如果没有virtual,也会屏蔽父类函数,如果有virtual就是重写。(发生在子类和基类中)

纯虚函数实例:

煮咖啡和煮茶叶都有,煮水,加入主料,加入辅料等操作

父类将通用的方法定义为纯虚函数,然后使用一个普通函数调用这些步骤

煮咖啡的子类重写父类的纯虚函数,煮茶叶的子类重写父类的纯虚函数。

主函数两种调用方式1.父类指针指向子类对象2.外部定义一个void test(基类名 * p){p->普通函数;delete p;} test(new tea);test(new coffee);

模板

函数模板(泛型编程)

  • 将功能相同类型不同的函数或类抽象成虚拟的类型,编译器自动将虚拟的类型具体化,提高代码重用性

  • 函数模板 要有template关键字修饰 关于T的类型会从主函数的实参中获取作相应的改变

  • 函数模板会编译两次,一次对函数模板本身,一次在函数调用时

//当函数模板和普通函数都存在时会优先调用普通函数

//也可以指定调用模板函数 Swap<>(a,b); 也可以直接告诉模板类型 Swap<int>(a,b)

//如果形参的两种类型不同,可以使用函数模板强制转换,Swap<int>(10,'a')

//函数模板也可以重载

template<typename T>

void Swap(T &a, T &b)

{

T tmp;

tmp=a;

a=b;

b=tmp;

return ;

}

template<typename T>

void test(T &a)

{

cout<<a<<endl;

}

template<typename T>

void test(T &a,T &b)

{

cout<<a<<b<<endl;

}

//当遇到结构体,自定义类型的时候,识别不到就可以使用函数模板具体化

template<typename T>

void test(T &a,T &b)

{

cout<<a<<b<<endl;

}

class data

{

int a;

friendly void test<data>(data a,data b);

}

//函数模板具体化

template void test<data>(data a,data b)

{

}

int main()

{

int a=10,b=20;

Swap(a,b);

char a='B',b='A';

Swap(a,b);

return 0;

}

类模板

  • 使用类模板时将声明和定义的文件改为.hpp文件

template<class T1,class T2>

class Data

{

private:

T1 a;

T2 b;

public:

Data();

Data(T1 a,T2 b)

{

this->a = a;

this->b = b;

}

void test()

{

cout<<""endl;

}

};

void main()

{

//不能直接使用无参构造,不会自动转换类型,不知道该转换什么类型

//所以使用类模板的使用,调用必须指定类型

Data<int int> ob1(10,20);

ob1.test();

Data<int char> ob2(10,'a');

ob2.test();

}

//在类外实现的类模板也要有template关键字

template<class T1,class T2>

class Data

{

private:

T1 a;

T2 b;

public:

Data();

Data(T1 a,T2 b)

{

this->a = a;

this->b = b;

}

void test();

};

template<class T1,class T2>

void Data<T1,T2>::test()

{

cout<<a<<b;

}

void main()

{

//不能直接使用无参构造,不会自动转换类型,不知道该转换什么类型

//所以使用类模板的使用,调用必须指定类型

Data<int,int> ob1(10,20);

ob1.test();

Data<int,char> ob2(10,'a');

ob2.test();

}

数组模板

template<class T>

class Array

{

private:

T *arr;//地址

int size;//数组大小

int capacity;//数组容量

public:

Array();//无参

Array(int capacity);//有参

//类中有指针成员所以要深拷贝

Array(const Array &ob);

~Array();//析构函数

Array& operator =(Array &ob);//重写 赋值运算符深拷贝

void pushBack(int elm);//插入元素

void sortArray();//排序

};

#endif // ARRAYCLASS_HPP

template<class T>

Array<T>::Array()

{

size = 0;

capacity = 5;

arr = new T[capacity];

memset(arr,0,sizeof(T)*capacity);

}

template<class T>

Array<T>::Array(int capacity)

{

this->capacity = capacity;

size = 0;

arr = new T[capacity];

memset(arr,0,sizeof(T)*capacity);

}

template<class T>

Array<T>::Array(const Array &ob)

{

//拷贝构造函数,就对象给新对象赋值

capacity = ob.capacity;

size=ob.size;

arr = new T[capacity];

memset(arr,0,sizeof(T)*capacity);

//要把就得内容拷贝到新的空间

memcpy(arr,ob.arr,sizeof(T)*capacity);

}

template<class T>

Array<T>::~Array()

{

delete []arr;

}

template<class T>

Array<T> &Array<T>::operator =(Array &ob)

{

//判断旧空间是否为空

if(arr !=NULL)

delete []arr;

capacity = ob.capacity;

size=ob.size;

arr = new T[capacity];

memset(arr,0,sizeof(T)*capacity);

memcpy(arr,ob.arr,sizeof(T)*capacity);

return *this;//返回this的对象

}

template<class T>

void Array<T>::pushBack(int elm)

{

//是否满

if(size == capacity)

{

capacity = 2*capacity;

T *tmp = new T[capacity];

//

if(arr != NULL)

{

memcpy(tmp,arr,sizeof(T)*capacity);

delete []arr;

}

arr = tmp;

}

arr[size] = elm;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值