我是做安卓开发的,学过一些java,现在学c++总是用java的方式来理解,给我造成了很多的问题。。。。。。谁用这个方式学谁知道~~~
比如单例模式在一个类中定义这个类的对象~~~vs总告诉我无法解析的外部符号,哈哈。
1.运行整个项目cmd窗口一闪而过
启动项目的时候有两种,一种f5调试运行,一种ctrl+f5不调试运行
调试运行:在不打断点和没有阻塞式方法的情况下f5会直接跑完整个程序
不调试运行:无论如何,在程序跑完之前会停顿等待输入任意值才会退出
有些环境也许在不调试运行的时候也不会等待输入才退出,那么需要手动写 cin.get();
2.文件.h和.cpp的区别
.h文件,用于声明类,变量和方法,导入其他.h文件或库文件系统的.h文件导入格式为#include <xxxx>
自己写的.h文件导入格式#include "xxx"
.cpp用于定义(在java里面叫做实现或者初始化).h文件中声明的类,变量和方法
在其他源文件中想使用这个类,变量和方法,导入相应的.h文件即可
2.1头文件重复包含导致项目报错
重复包含头文件会导致项目出错(系统头文件可以被重复包含,例如,iostream),
例如a.h,包含b.h,c.h包含a.h的同时又包含了c.h,因为你导入a.h的时候,实际上已经导入了c.h,但你又手动导入了一次c.h会导致头文件重复包含
一般在.h文件里面写声明,如果要用到其他的类,并不需要在.h文件中导入,只需要写前置声明即可,例如
class Person;(因为在.h文件里面做声明的时候你并不需要用到对象的具体成员)
之后在具体需要用到person对象的成员的时候才需要在.cpp文件里面导入Person.h
.h文件的写法
#ifndef __MYUSER_H //判断是否有了名为__MYUSER_H的宏(用于防止头文件被重复导入) #define __MYUSER_H<span style="white-space:pre"> </span>//如果没有则声明 //包含要用到的系统头文件 #include <iostream> //如果需要,前置声明 class Person; //声明其他你需要的代码,例如 class Good { public: Person * person; void show(); }; #endif // __MYUSER_H
3.写项目之前
在main.cpp里面需要用上命名空间using namespace std;如果是空项目,在头文件里面建立一个.h文件,例如all.h,在里面include 你在其他大部分文件里面都要用的头文件和命名空间
这样当你写其他.h文件的时候,就没必要每次都要写include <iostream> include xxxxxx using xxxxxx,只需要导入你写的这个all.h头文件即可
4.变量问题
int a;声明一个变量a = 5;初始化一个变量
写在文件里的就叫成员变量(java每个.java文件都必然有个类,写在类外面的除了类就会报错,c++初始main方法并不在类中,所以写在文件里面即为成员变量)
无符号变量有符号变量:意思是有符号的正负数都可以存,无符号的只能存正数,存储范围因为无符号的不能存负数,所以取值范围为有符号的负数+正数
默认初始化和java一样,整数0,小数0.0
查看最大值:
include <limits> 然后cout<<INT_MAX<<endl;//int类型最大值,long以及其他整形依次类推
iinclude <float.h> 然后cout<<DBL_MAX<<endl;//double最大值
赋值问题:
赋值超出范围:比如short最大值为32767,赋值为32768,你会看到他的值变成了-32768(在java里面就直接报错了)
5.cin问题
如果刚开始写程序,必然用控制台应用程序例如计算器,银行,学生管理系统在java里比较经典的例子来试手,然后你会发现代码:
int a = 0; cin>>a;你输入45,结果没问题,你输入ab的时候vs不会告诉你类型异常。程序依然可以跑~~~~但是while循环开始无限执行了~~
当你输入ab的时候,cin接收输入并放入整型变量a中,如果接收错误,那么cin的状态就会改变。你可以cin的状态来判断是否接收异常。
//判断cin是否接收错误,如果是则清空cin缓存返回false,否则直接返回true bool isCinGood(){ if (cin.fail()) {//如果cin接收异常就会返回true cin.clear(); //定位cin错误的位置 cin.ignore(1024,'\n');//开始删除(跳过)碰到'\n'(即回车符)之前的1024个字符 return false; } return true; }
6.万物皆对象
//一个类 class MyPerson { public: //权限符,当前权限符以下和下一个权限符以上的都属于当前权限 ~MyPerson(){} static MyPerson* getInstance();//声明获取对象的方法 string name; //一个成员变量 private : static MyPerson *myPerson; MyPerson() {}//不让new对象 }myPerson1;这个是C++的类,总体来说,看上去和java是差不多的
MyPerson.cpp
#include "MyPerson.h" MyPerson* MyPerson::getInstance() { if (myPerson == NULL) { myPerson = new MyPerson(); myPerson->name = "hehehe"; } return myPerson; } MyPerson* MyPerson::myPerson = NULL;
c++类的默认权限修饰符:在没有写权限修饰符的情况下,默认为private
c++创建对象:创建对象并不一定使用new,
Person person;//这就已经创建了一个对象,和普通变量的作用域一样,使用在栈中,出了作用域自动回收。
Person* person = new Person();//用new创建一个对象,保存在堆中,使用完毕需要手动回收
权限修饰符(public,private,proxxxx):只需要写一个,在这个权限修饰符以下和下一个权限修饰符以上的都是当前权限
MyPerson()是构造方法,对象创建的时候会调用,这里设置为private则在其他文件中不允许new对象
~MyPerson()是析构方法,对象被销毁的时候会调用,一般用来释放一些对象占用的资源
自带对象:最后一行的myPerson1的意思是创建一个名为myPerson1的对象
单件(单例)模式:上面.h文件中的static MyPerson *myPerson;//声明(声明)
和.cpp文件中的MyPerson* MyPerson::myPerson = NULL;//定义(初始化)
如果你不写定义,vs会告诉你无法识别外部xxxxx,其他的方法(包括静态方法),静态成员变量(不包括普通成员变量)也是需要定义。
7.接口
C++没有接口,但c++支持多继承,写一个抽象类,继承即可(作用和接口一样)
class inter{ virtual void show()=0; };被virtual修饰的是虚函数
virtual void show()=0;即纯虚函数(java中的抽象方法),
虚函数和纯虚函数的区别
虚函数一定要写定义(实现或者叫做方法体),纯虚函数不用
有虚函数的类可以创建对象,有纯虚函数的类不允许创建对象
(在java中的体现为纯虚函数即为拥有抽象方法的类必须为抽象类,抽象类不允许创建对象,只是c++不显示的让你把类变成抽象类而已)
8.类模版,函数模版
模版即java的泛型,在方法前使用<T>或者<T,K>等方式限制传递类型为T或者为任意类型的东西9.字符串截取
在c++中可以使用string(开始的s是小写),需要include <string>java中对字符串的截取可以写为str.split(",");
但c++没有,做截取需要用到两个方法
string name = "123:456:789123456"; //截取name1 std::size_t found = name.find(":"); int index; string name1 = name.substr(0, found); cout << "name1:" << name1 << endl; //截取name2 index = found; //记录第一个冒号的位置 found = name.find(":", found + 1, 1); //找到第二个冒号的位置,中间的就是密码 string name2 = name.substr(index + 1, found - index - 1); cout << "name2:" << name2 << endl; //name3的位置为,第二个冒号到字符串长度 index = found; index++; string name3 = name.substr(index, 200); cout << "name3:" <<name3<< endl; cout <<"length:"<< name3.length() << endl;
第一个方法,string.find(":");重载:string.find(":",size_t,int);
string.find(":"); //查找冒号的位置,遇到则返回下标,否则返回-1
备注:之所以没找到的时候,输出size_t会看到一个很大的数字,是因为size_t为unsigned int(无符号整形),-1超出最小取值范围,C++默认从最大那一边开始取值
string.find(":",size_t,int);
参数说明:
1.需要查找的字符串(宽字符)
2.这一次的size_t(上次的size_t+1就是这一次的,即忽略已经碰到的次数)
3.上一次find的时候,传入查找字符串(宽字符)的长度,比如传入的是":",则长度为1
第二个方法,string.substr(int start,int end);//从下标start开始截取字符串(包含start下标的字符),一直到下标为end的字符(不包括end)结束。
参数说明:
1.开始截取的下标
2.结束的下标