c++学习笔记,控制台应用程序问题

我是做安卓开发的,学过一些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.万物皆对象

MyPerson.h
//一个类
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.结束的下标

猜你喜欢

转载自blog.csdn.net/qq_26559913/article/details/53019256