QT--C++简学
2.1C++语言的新特点(对于C语言来说)
赋值:直接 ------- int x(100) 在定义的时候就可以赋值,相当于 x=100;
2.2输入(cin)--------输出(cout)
2.2.1
cout << x<<endl; //一个变量 --------printf
cout <<x <<y <<endl; //两个变量
endl-------------------------- 相当于换行 /n
好处是不用指定变量的类型,C语言中打印数据的时候就必须指定是什么类型的变量 比如说:%d %s %f 之类的
2.2.2
cin >> x ; ----------scanf
cin >> x >>y;
2.3命名空间(using namespace std)
namespace 和 类是不一样的东西,不过里面具体的含义没弄明白,namespace 目前来看是解决命名冲突用的,别的点以后在补充吧
如果说要用到 cout and cin ,则要有命名空间的声明,实际上 这两个函数就是在std域中
类似这样的: std::cout or std::cin
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 cout << "Hello,World!" <<endl ; 6 return 0; 7 }
PS: 这里要注意一下 include 里面是instream 是没有.h
为什么要用这个东西?主要是说 C++标准库里面的东西很多可能和自己写的会重复名字,这样可以方便区分。理论上其实调用标准库的东西都是要加上一个 std 的,但是如果没 有相同名字的类的话,就可以偷懒不加std ,引用的方式是 std ::xxxx。
Example :在ubuntu下创建命名空间并用g++编译器运行起来
流程:新建一个文件夹----->创建一个xxxx.cpp文件(用QT创建?)-输入代码-运行命令行:g++xxx.cpp -o xxx
1 1 #include <iostream> 2 2 using namespace std; 3 3 4 4 namespace A 5 5 { 6 6 int x = 1; 7 7 void fun() { 8 8 cout<<"A namespace"<<endl; 9 9 } 10 10 } 11 11 using namespace A; 12 12 int main() 13 13 { 14 14 fun(); 15 15 A::x = 3; 16 16 cout<<A::x<<endl; 17 17 A::fun(); 18 18 return 0; 19 19 }
运行的结果:

2.4类和对象
类,就是顾名思义某一类的东西,通过把一类东西的特点和某些逻辑的实现(理解成函数差不多)放在一个地方,按下面的方式定义,类名一般首字母大写,
其实有点像结构体,但是比结构体感觉高级一点。(下面代码有点问题,应该补一个public:)
1 class Dog{ 2 3 int age; 4 5 string name; 6 7 double weight; 8 9 void run(){ 10 11 std::cout <<"xxx" << endl; 12 } 13 14 };
引用类去定义变量就是对象实例化,这个变量就叫做对象,比如说,上面定义了一个“狗”类,说明“狗“这种生物都具有哪些特点以及行为,对象实例化的就是具体到哪一条狗上
1 Dog dog1; 2 Dog don2;
这里的dog1,dog2就是对象了,上述的实例化是从栈中实例化,给这个对象分配内存是在实例化时到函数结束,系统会自动收回内存
下面这个是从堆中实例化,系统无法自动收回内存,所以需要delete();删除
1 #include <iostream> 2 using namespace std; 3 4 class Dog{ 5 public: 6 string name; 7 int age; 8 double weight; 9 10 void run(){ 11 std::cout<<name<<"的年龄(岁)是:"<<age<<endl; 12 std::cout<<"体重(kg)是:"<<weight<<endl; 13 } 14 }; 15 16 int main() 17 { 18 Dog dog1; //栈中实例化 19 Dog *dog2 =new Dog(); //堆中,dog2其实是一个指针,注意这个地方,其实是可以分成两部分的,先是 Dog *dog2 ; //即声明指针 20 if(dog2==NULL){ // 再 dog2=new Dog(); //实例化对象,注意是到这一步才是实例化对象,上面只是单纯的声明指针 21 return 0; 22 } 23 24 dog1.name ="dog1"; 25 dog1.age = 2 ; 26 dog1.weight= 35 ; 27 dog1.run() ; 28 29 dog2->name="dog2"; 30 dog2->age = 5 ; 31 dog2->weight=33; 32 dog2->run(); 33 34 delete dog2; 35 dog2 = NULL; 36 return 0; 37 }
34.35的意思是释放掉dog2占据的内存,同时将指针(*dog2)指向NULL(空指针)
2.5构造函数和析构函数
其实在定义类的时候如果没有定义这两个函数的话,也会自动生成的;
构造函数就是和类名相同的函数,而且没有任何的返回类型(连void 都没有),在对象刚被实例化的时候就会自动调用一次,一般来说会被用于类里面变量的初始化,(可以重 载,再说)
for example :Dog(){}
析构函数是在构造函数前面加上一个取反的符号~,在对象的生命周期结束的时候(是在例化该对象所在的函数跑完的时候?对的,测试结果确实这样)会系统会自动调用一次, 调用时释放内存
for example :~Dog() {} () 里面不能加参数
下面的是测试的程序
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Dog{ 7 8 public: 9 Dog(){ 10 cout <<"构造函数执行了"<<endl; 11 } 12 13 ~Dog(){ 14 cout <<"析构函数执行了"<<endl; 15 } 16 17 }; 18 void test(){ 19 Dog dog; 20 cout <<"测试程序运行" <<endl; 21 } 22 23 int main(){ 24 test(); 25 cout<<"主函数正在执行" <<endl; 26 27 return 0; 28 }
运行的结果是:

2.6this 指针
这个东西好像没啥太多作用,就目前的阶段来看,主要还是为了做变量命名的区分,大多数的情况下还是用不到的,
感觉QT项目里面就经常会遇到这个this,需要注意的是无论是以什么方式去用这个“this”,这个“this”指的都是当前这个类
有一种情况会用到就是当类里面的成员变量的名字和方法的形参重复了的时候,为了区分函数里面的变量,在成员函数那里就要加上 this->
2.7继承(父类和子类)or(基类和派生类)
一个父类可以有多个子类,定义的方式为 class 子类名 :public(protected or private) 父类名
公有继承(public):父类的public and protected 也是子类的public,父类的private 无法被子类直接访问,但是可以通过调用父类的public和protected去间 接调用
保护继承(protected):父类的public和protected是子类的protected
私有继承(private): 父类的public和protected 是子类的private
2.8重载(函数重载和符号重载)
1.函数重载
在一个作用域内声明几个名字相同,作用相似(相同)的函数,但是每个函数的形参其实是不一样的(指排列的顺序、数据类型、参数的数量),这样在调用这些同名函数 的时候,需要分别写入合适的参数,系统会自动识别到具体的对应函数,当然,如果输入的参数是原函数中所不具有的,那么编译器就会报错
2.符号重载(有点看不懂这个,据说用到的不多?再补充吧)
2.9多态(感觉和C语言里面的虚函数weak很像)
形成多态必须具备三个条件:
1. 必须存在继承关系;
2. 继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字 virtual 声明的函数,在派
生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);
3. 存在基类类型的指针或者引用,通过该指针或引用调用虚函数。
有个点需要注意一下,就是说如果单纯的写一下 virtual的话,这个虚函数就要在里面写点什么逻辑(写什么应该无所谓),如果是啥都不想写的话,就要用到纯虚函数了
,类似这样的 virtual void(合适的函数类型) xxxxx()=0; 注意这里有“ ;” ,写虚函数的话在class里面实现就没有这个了
有点抽像,看看例子先
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 /* 定义一个动物类 */ 6 class Animal 7 { 8 public: 9 virtual void run() { 10 cout<<"Animal 的 run()方法"<<endl; 11 } 12 }; 13 14 /* 定义一个狗类,并继承动物类 */ 15 class Dog : public Animal 16 { 17 public: 18 void run() { 19 cout<<"Dog 的 run()方法"<<endl; 20 } 21 22 }; 23 24 /* 定义一个猫类,并继承动物类 */ 25 class Cat : public Animal 26 { 27 public: 28 void run() { 29 cout<<"Cat 的 run()方法"<<endl; 30 } 31 32 }; 33 34 int main() 35 { 36 /* 声明一个 Animal 的指针对象,注:并没有实例化 */ 37 Animal *animal; //这里重要,必须通过这样的指针方式 38 /* 实例化 dog 对象 */ 39 Dog dog; 40 /* 实例化 cat 对象 */ 41 Cat cat; 42 43 /* 存储 dog 对象的地址 */ 44 animal = &dog; 45 /* 调用 run()方法 */ 46 animal->run(); //这里如果不是虚函数的话,就会直接指向父类的run方法 47 48 /* 存储 cat 对象的地址 */ 49 animal = &cat; 50 /* 调用 run()方法 */ 51 animal->run(); 52 return 0; 53 }

3.0数据封装
这里开始用到 private,主要的思想就是利用private的不可调用性质(外部不可调用,內部的public还是可以用的)
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Dog 6 { 7 public: 8 string name; 9 10 Dog(int i = 0) 11 { 12 total = i; 13 } 14 15 void addFood(int number) { 16 total = total + number; 17 } 18 19 int getFood() { 20 return total; 21 } 22 private: 23 int total; 24 }; 25 26 27 int main() 28 { 29 Dog dog; 30 31 dog.name = "旺财"; 32 33 dog.addFood(3); 34 dog.addFood(2); 36 cout<<dog.name<<"总共获得了"<<dog.getFood()<<"份食物"<<endl; 37 38 return 0; 39 }
3.1数据抽象
3.2接口(抽象类)
就是类里面有纯虚函数的时候,这个类就叫做抽象类,抽象类不能实例化
这个地方和上述多态部分看起来有点像,但是感觉只是结果一样,实现的思想不同
#include <iostream> using namespace std; /* 定义一个动物类 */ class Animal { public: virtual void run() = 0; //这里的纯虚函数注释掉也是一样的运行结果,但是前后的思想逻辑好像就不太一样 }; /* 定义一个狗类,并继承动物类 */ class Dog : public Animal { public: void run() { cout<<"Dog 的 run()方法"<<endl; } }; /* 定义一个猫类,并继承动物类 */ class Cat : public Animal { public: void run() { cout<<"Cat 的 run()方法"<<endl; } }; int main() { /* 实例化 dog 对象 */ Dog dog; /* 实例化 cat 对象 */ Cat cat; /* dog 调用 run()方法 */ dog.run(); /* cat 调用 run()方法 */ cat.run(); return 0; }
浙公网安备 33010602011771号