C++学习之路
Posted David_Han008
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习之路相关的知识,希望对你有一定的参考价值。
C++与C的关系:所有C程序都可以在C++的编译环境中运行。
c++比c语言之多添加了bool(布尔类型)
新的初始初始化方法:
随用随定:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(void)
{
cout<<"请输入一个整数:"<<endl;
int x=0;
cin>>x;
cout<<oct<<x<<endl;//将该整数转变成8进制
cout<<dec<<x<<endl;//将该整数转变成10进制
cout<<hex<<x<<endl;//将该整数转变成16进制
cout<<"请输入一个布尔值(0/1):"<<endl;
bool y=false;
cin>>y;
cout<<boolalpha<<y<<endl;//boolalpha表示的是布尔值
system("pause");
return 0;
}
不由得嘚瑟一下,出结果了:这样就可以再8进制,10进制,16进制之间自由 转换了。
C++的命名空间:用名字划取名字定义命名空间namespace
::表示的是,使用A命名空间中的x。
2016年8月30日,我已经没有那么多时间了,我看了看那些课程,自己要加快速度了,目前自己打算光速掌握C++,我必须让自己痛苦,然后掌握opencv至少在上研究生之前可以做吧人脸识别简单的东西做出来吧。
引用:在计算机中,引用就是变量的别名。
输出的结果是10
结构体引用:
这个结构体的名字叫做Coor。
然后在函数中使用这个结构体
指针:
说明:
函数参数做引用时:
c++的关键字const:是用来控制变量是否可以变化的。
const与变量之间的关系:也就是将一个变量变成一个常量。
const与指针类型的关系:const int*p=NULL;与 int const*P=NULL是完全等价的
函数参数默认值:
如果函数重要些默认值,默认值必须写在最右边。格式:
红字表示函数的声明,黑字表示函数的定义。
函数重载:
就是两个函数的名字一样,但是参数的个数不同,就是函数的重载。
内联函数:内联函数的关键字:inline。:
就是将过程放到main函数里面执行。
c++内存管理:申请和归还内存资源。
申请内存,使用运算符:new;释放内存,使用运算符:delete
申请内存 int*p=new int;释放内存 delete*p.
申请一个块内存:int *arr=new int[10];释放块内存: delete []arr;
判断申请内存是否失败:if(NULL==p)则说明内存分配失败了,申请内存的时候需要判断内存是否申请成功,释放内存需要将其设为空指针
例子:
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(void)
{
int *p=new int;//申请内存
//判断申请内存是否成功
if (NULL==p)
{
system ("pause");
return 0;//如果申请失败我们就退出‘如果申请成功了我们就将P赋值为20
}
*p=20;
cout<<*p<<endl;
delete p;//释放内存
p=NULL;//将指针设置为NULL
system ("pause");
return 0;
};
类(定义完类以后,一定要写一个分号)
对象:
数据成员+成员函数=完成的类
封装:就是只给用户一些他们关心的信息。
类的访问限定符(作用:选择暴露)1、public;2、protected;3、private
实例化,有两种方式,一种是从堆中实例化,一种是从栈中实例化。
从栈中实例化:
从堆中实例化:
从堆中实例化需要释放内存,而在栈中不用
。!
总结:先实例化,然后再访问
对象成员的访问方法
举例说明:
堆和栈之间的区别
内存的分配方式不同
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)— 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事的方式实例化一个对象:
举例说明
这是一个求三角形面积的程序
demo.cpp
#include <iostream>
#include "Triangle.h"
using namespace std;
int main()
{
Src_Triangle *Src_dTriangle = new Src_Triangle();
cout << "请输入三角形的三条边:" << "";
cin >> Src_dTriangle->A_side >> Src_dTriangle->B_side >> Src_dTriangle->C_side;
Src_dTriangle->Src_judge(Src_dTriangle->A_side, Src_dTriangle->B_side, Src_dTriangle->C_side);
cout << "三角形的面积是:" << Src_dTriangle->getTriangleArea(Src_dTriangle->A_side, Src_dTriangle->B_side, Src_dTriangle->C_side) << endl;
delete Src_dTriangle;
Src_dTriangle = NULL;
system("pause");
}
Triangle.h
#include <iostream>
#include <cmath>
using namespace std;
class Src_Triangle
{
public:
double A_side;
double B_side;
double C_side;
double Area;
void Src_judge(double a, double b, double c);//定义了一个bool类型
double getTriangleArea(double a, double b, double c);//定义了求解方法
};
void Src_Triangle::Src_judge(double a, double b, double c)
{
if ((a + b >= c)&(b + c >= a)&(a + c >= b))
{
cout << "您输入的三个数值可以构成三角形" << endl;
}
else
{
cout << "您输入的三个数值无法构成三角形" << endl;
}
}
double Src_Triangle::getTriangleArea(double a, double b, double c)
{
double m;
m = (a + b +c) / 2;
return sqrt(m*(m - a)*(m - b)*(m - c));
cout << "也就是说这条程序是通的" << endl;
};
、##########################################################################
使用栈的实例化方式
#include <stdlib.h>
#include <iostream>
using namespace std;
class Coordinate
{
public:
int x;
int y;
void print_x()
{
cout<<x<<endl;
}
void print_y()
{
cout<<y<<endl;
}
};
int main(void)
{
Coordinate coor;
coor.x=10;//给数据成员进行赋值
coor.y=1;
coor.print_x();//运用成员函数进行打印的操作
coor.print_y();
system("pause");
return 0;
}
(2)使用堆的方式实例化对象
#include <stdlib.h>
#include <iostream>
using namespace std;
class Coordinate
{
public:
int x;
int y;
void print_x()
{
cout<<x<<endl;
}
void print_y()
{
cout<<y<<endl;
}
};
int main(void)
{
Coordinate *coor=new Coordinate();
coor->x=10;//给数据成员进行赋值
coor->y=1;
coor->print_x();//运用成员函数进行打印的操作
coor->print_y();
delete coor;
coor=NULL;
system("pause");
return 0;
}
如何判断申请内存是否失败:
#include <stdlib.h>
#include <iostream>
using namespace std;
class Coordinate
{
public:
int x;
int y;
void print_x()
{
cout<<x<<endl;
}
void print_y()
{
cout<<y<<endl;
}
};
int main(void)
{
Coordinate *coor=new Coordinate();
if (NULL==coor)
{
cout<<"申请内存失败"<<endl;//如果申请内失败的话,就会输出这条语句
return 0;
}
coor->x=10;//给数据成员进行赋值
coor->y=1;
coor->print_x();//运用成员函数进行打印的操作
coor->print_y();
delete coor;
coor=NULL;
system("pause");
return 0;
}
栈用“.”堆用“->”
如果是数组的话,用这种方法:
如果是访问的是一个类里面的数组,那么要用for语句
string的操作:
数据的封装:
用函数来封装数据成员
m_下划线有助于搜索,str表示数据类型。
(3)
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
void setName(string _name)
{
m_strName=_name;
}
string getName()
{
return m_strName;
}
void setGender(string _gender)
{
m_strGender=_gender;
}
string getGender()
{
return m_strGender;
}
int getScore()//int表示他的返回值
{
return m_iScore;
}
void initScore()
{
m_iScore=0;
}
void study(int _score)
{
m_iScore+=_score;
}
private:
string m_strName;
string m_strGender;
int m_iScore;
};
int main(void)
{
Student stu;
stu.initScore();//将学分初始化
stu.setName("David Han");
stu.setGender("男");
stu.study(100);
cout<<stu.getName()<<endl<<stu.getGender()<<endl<<stu.getScore()<<endl;//这里一定要加括号,因为加了括号才是函数
system("pause");
return 0;
}
程序运行结果:
类外定义:
有两种形式:1、同文件类外定义;
总结一下:类外定义,其实就是在类名::然后在要定义的函数,就可以啦。
2、(常用)分文件类外定义
先定义一个头文件(.h文件)然后在另外一个cpp文件中使用。
头文件里装的数据成员
在头文件里面定义:数据成员和声明成员函数
注意:
h文件要装:
在CPP文件里定义:具体的成员函数
举例:
值得注意的是:定义的类名,和头文件的名字要一样。
内存按照用途被划分的5个区:
栈区的特点就是内存由系统进行分配和控制。堆区,用delete来回收
定义一个类,在这个类被实例化之前是不会占用内存的。对象的初始化:有两种类型,有且仅有一次的初始化,和根据条件的初始化
构造函数:(重要)作用就是初始化对象,省事。
构造函数在对象实例化的时被自动调用。
构造函数要与类同名,
构造函数没有返回值。
构造函数可以进行重载。
无参数构造函数:
举例:
有参数构造函数:
举例:
当然构造函数也是可以重载的:
举例:
举例说明,先是demo.cpp文件
#include <iostream>
#include <stdlib.h>
#include <string>
#include "teacher.h"
using namespace std;
int main(void)
{
teacher t1;//t1这个类是为了无参函数
cout<<t1.getName()<<endl<<t1.getAge()<<endl;
teacher t2("DDavid",24);//记住有参的析构函数这么赋值,和无参的析构函数赋值方式不同。
cout<<t2.getName()<<endl<<t2.getAge()<<endl;
system("pause");
return 0;
}
然后是teacher.文件
#include <iostream>
#include <string>
using namespace std;
class teacher
{
public:
teacher();//第一点,析构函数的赋值也是在teacher.cpp中进行的。
teacher(string name, int age);
void setName(string name);
string getName();
void setAge(int age);
int getAge();
private:
string m_strName;
int m_iAge;
};
最后是teacher.cpp文件
#include "teacher.h"//这里只用写这一条语句就够了。
teacher::teacher()//无参构造函数 注意的一点的是,这里千万不要写分号
{
m_strName="David Han";
m_iAge=23;
cout<<"这是无参构造函数建立的"<<endl;
}
teacher::teacher(string name, int age)//有参构造函数
{
m_strName=name;
m_iAge=age;
cout<<"这是有参构造函数建立的"<<endl;
}
void teacher::setName(string name)
{
m_strName=name;
}
string teacher::getName()
{
return m_strName;
}
void teacher::setAge(int _age)
{
m_iAge=_age;
}
int teacher::getAge()
{
return m_iAge;
}
运行的结果图:
初始化列表:
举例,在上面的程序中
也就是说在有参构造函数后面用冒号,然后如果是多个变量用逗号隔开。
同时,在.h文件中可以采用上述的这种默认构造函数。
运行结果:
当然,也可以在demo.cpp中用这种方式进行赋值:
2016年8月31日
简单的规划一下:从今天到9月9日,吧慕课上面的C++学完,包括游戏开发,然后是opencv的书看完,10天的特训,听起来就热血沸腾了,来吧!!
拷贝构造函数:定义格式:类名(const类名&变量名)举例:Student (const Student &stu)特点:
1、如果没有自定义的拷贝构造函数,则系统自动生成一个默认的拷贝构造函数。2、当采用直接初始化或复制
初始化对象时系统自动调用拷贝构造函数。
析构函数:在完成任务以后会被自动销毁,为了释放内存。定义格式:~类名()举例:
析构函数的特点:
析构函数也不能重载。
类由成员函数和数据成员组成,如果担心你的类和别人的类重名,那么可以使用不同的命名空间来加以区分。
数据成员包含上面5种。
成员函数的分类
将上面所学到的举例说明:
#include <iostream>
#include <string>
using namespace std;
/**
* 定义类:Student
* 数据成员:m_strName
* 无参构造函数:Student()
* 有参构造函数:Student(string _name)
* 拷贝构造函数:Student(const Student& stu)
* 析构函数:~Student()
* 数据成员函数:setName(string _name)、getName()
*/
class Student
{
public:
//无参构造函数
Student()
{
m_strName=",";
}
//有参构造函数
Student(string _name)
{
m_strName=_name;
}
//拷贝构造函数
Student(const student& stu){};
//析构函数
~Student(){};
void setName(string);
string getName();
private:
string m_strName();//数据成员m_strName
};
//成员函数setName
void Student::setName(string _name)
{
m_strName=_name;
}
//成员函数getName
void student::getName()
{
return m_strName;
}
int main(void)
{
// 通过new方式实例化对象*stu
Student *stu = new Student;
// 更改对象的数据成员为“慕课网”
stu->setName("慕课网");
// 打印对象的数据成员
cout<<stu->getName()<<endl;
//释放内存(利用堆要释放内存)
delete stu;
stu=NUll;
return 0;
}
对象数组:
所谓的遍历,就是打印出数组当中的信息。
对象成员:
深拷贝和浅拷贝:
总结一下:各种格式:
对象指针:就是一个指针,他来指向一个对象。不懂!
2016年9月1日
小技巧:选取一段代码,按住Ctrl+k+c就可以将所选代码注释掉。
对象成员指针:不懂哦!
this指针:如果参数与数据成员同名会怎样呢?用this指针,this指针就是指向对象自身数据的指针。用法:
建议数组成员的命名:m_(数据类型)(数据名称)
常对象成员和常成员函数,用法:
对象指针和对象引用:用法:
我现在开始继承篇了
为什么要继承:
工人这个类中,有和人这个类中一样的属性,那么我们就可以用继承的方式,达到简化定义工人这个类,只用定义工人这个类中特有的两个即可。(前提是人包含工人)
用法:
那么我们可以做如下定义:
我们称工人类是人类的派生类。人类是工人类的基类。或者说,工人类是子类,人类是父类。
继承方式:1、共有继承,格式:class A:public:B。2、保护继承,格式:class A:protected:B。3、私有继承,格式:class A:private:B。
三种继承方式的差异:
覆盖和隐藏:
多继承和多重继承:
多继承的写法:
class Worker
{
};
class Farmer
{
};
class MigrantWork:public Worker,public Farmer
{
};
虚继承:关键字virtual
通过宏定义来解决重定义。#ifndef #define #endif
举例:
面向对象的三大特性,封装,继承,多态
多态:相同对象收到不同的消息或不同对象收到相同消息时产生不同的动作。
静态多态VS动态多态,其中,静态多态也叫作早绑定。动态多态也叫作晚绑定
虚函数:格式:
动态多态存在的问题:内存泄漏
virtual+析构函数=虚析构函数
virtual在函数中的使用限制:1、不能修饰普通函数,2、不能修饰静态的成员函数,3、不能修饰内联函数。
函数指针,如果一个指针指向的是函数,就是函数指针
纯虚函数:区别:纯虚函数没有函数体,并且在函数后面要写“=0”.
2016年9月2日
说点感悟吧,在没有基础编程之前,觉得编程很神奇,然后很想学习。然后到现在是接触和很多虚头巴脑,似懂非懂的感念,什么类,引用,封装,多态,对象,虚函数,隐藏和覆盖,觉得很抽象。我的继续学下去。
抽象类:就是包含纯虚函数的类
抽象类,不允许实例化。
抽象类的子类也是抽象类。
接口类:仅含有纯虚函数的类就是接口类。(在类中没有数据成员,仅有成员函数且成员成员函数都是纯虚函数)
RTTI:运行时类型识别
使用dynamic_cast注意事项:1、只能应用于指针和引用的转换;2、要转换的类型中必须包含虚函数。3、如果转换成功返回子类地址,转换失败返回NULL
typeid注意事项:1、type_id返回一个type_info的对象引用;2、如果想要通过基类指针获得派生类的数据,基类就必须带有虚函数。;3、只能获取对象的实际类型
异常处理:对有可能发生异常的地方做出预见性的安排。关键字:try(尝试)…catch(捕获)… throw…(抛出异常)
用法:
模板
函数模板
模板,模板函数,模板类
在这上面三条语句当中,int float char 这三种数据类型,但是他们具体实现的函数是一样的,所以我们就是想吧函数作为参数传入进去,然后让计算机帮我们实现这三条语句的编写
函数模板:关键字:template;typename;class
类模板:模板代码不能分离编译
在函数名前面加上
还是上面的这个例子
这个就是函数模板
template <class T>
T max(T a,T b)
{
return (a>b)?a:b;
}
在实际使用的时候
int ival=max(1,2);这个就是模板函数
或者
char ival=max<char>('A','B');
template <typename T>//用于声明这个函数是一个模板
其中,T是一个类型名
typename 就是类名
template就是是一个关键的模板参数的
友元全局函数,友元对象函数:关键字friend
友元类,就是friend+类名
A的友元可以自由的访问A的成员函数和数据成员
B就是A的友元
class A
{
friend void func(A*p);
friend class B;
}
友元的注意事项:
友元的关系不可以传递;友元关系的单向性;友元声明的数量和形式不受限制。友元的使用破坏了封装性。
静态数据成员:注意事项:静态数据成员必须单独初始化;静态成员函数不能调用非静态成员函数和非静态数据成员,非静态的数据成员可以调用静态的数据成员和成员函数;静态数据成员只有一份,并且不依赖对象而存在。
重载操作符
运算符重载:就是给原有的运算符赋予新的功能。本质就是函数重载。关键字:operator
举例:一元运算符的重载:成员函数的重载,友元函数的重载 二元运算符的重载
重载操作符的使得一个自定义类型的可以像一个基本类型一样支持加减乘除操作
STL模板
STL:C++标准模板库:举例说明:vetor向量:就是对数组的封装。
STL里面几乎封装了所有常见线性数据结构
1、vector 容器
2、list 链表
3、map 映射
4、string 字符串
5、queue 队列
6、stack 栈
7、set 集合
8、dequeue
在创建at/front/back这函数用于访问数组中的元素
at用于检索访问的任意位置的元素
front用于检索头位置的元素
back 用于检索尾位置元素
向量的初始化方法:
迭代器:iterator
到这里我第一轮的学习就算是学习完了,然后我决定就是我再学习一边慕课网的知识,吧上面的一些概念,和一些自己跳过的知识点在学习一边,其实也没那么困难。然后明天开始继续学习C++,不学opencv,仅仅辅助学习,学习就是这样,一心一意。弄好一个算一个。opencv linux(cenos)都是这个阶段要学习的。
内部类
class AAA
{
public:
class inner
{
public:
char name[64];
}
}
int main()
{
AAA::inner a;//实例化该内部类
return 0;
}
仅仅使用部分的空间的部分名字
using adsf::asdf;
异常
异常处理有三个关键字:throw、try、catch.
throw 用于抛出
try 用于监视
catch用于剥啄
2016年10月6日
以后过去好久了。继续C++的学习之路,大概接触 C++已经3个月了,今天我要把在VS中如何进行单步调试,然后看看这个过程的变量的东西学好
http://jingyan.baidu.com/article/1709ad808ad29f4634c4f00b.html
这个链接总结的很好
队列篇
数据结构是指的相互之间存在一种或多种特点关系的数据元素的集合
应用:自动排号机
面向对象的
以上是关于C++学习之路的主要内容,如果未能解决你的问题,请参考以下文章