指针
用来保存某种类型的变量的地址的变量,取地址& ->知道变量取地址,某个地址的变量: *地址
成员指针,(*地址).成员,地址->成员
向函数传递参数的时候,如果希望函数能操作某个变量里的数据,就把变量的地址传递给函数,函数里就可以根据地址找到内存中的那个变量,从而取得或者改变变量里的值。
地址运算
+n,-n 始终与地址的类型为单位来走,例如整形移动4*n个字节 p+n,p-n
P[i] ==> *(p+i)
#include<iostream> using namespace std; int main() { int a[5] = {11,12,13,14,15}; int *p = a; cout<< a[2] << ‘,‘<<p[2]<<endl; cout<< *(a+2) << ‘,‘<< *(p+2)<<endl; cout<< 2[a] << ‘,‘<< 2[p] <<endl; system("pause"); return 0; }
p-q结果是多少个单位,单位为sizeof(地址类型),比较
指针定义时建议带初始化从而避免野指针,不要通过空指针或目标已经释放掉的指针去找变量(*),不要返回非静态局部变量的地址作为函数的返回值,作为函数形参的指针如果不用于改变目标的值就尽量加const修饰保护目标不被误伤。
X const *p <==> const X *p; p指向的只读X类型的数据
函数指针
int f1(char* ,int) -> int (*p) (char* int);
数组指针
int a[8]; ->int (*p)[8]
输出地址:
输出字符类型的地址,为了保持与C语言的兼容,系统处理成输出字符串
#include<iostream> using namespace std; int main() { char c = ‘a‘; char *p = &c; int i= 1; int *q = &i; cout << p <<‘,‘<<q<<endl; system("pause"); return 0; }
引用
引用一个常亮应该对引用加const.用临时结果(运算结果或者函数的普通返回值)去初始化一个引用时,也应该对引用加const
const int x=20;
const int& rx = x;
面向对象 Object-Oriented Programming
C语言是一系列的函数描述程序的工作过程,称为过程。
C++把程序里面的数据和对数据的操作合起来看作一个实体称为对象,编程工作就是操纵这些对象相互作用来完成程序的功能,这样的编程方式称为面向对象。
抽象:每个实体都有很多的数据和很多的行为,只提取咱们关心的数据和行为。
封装:用抽象的结果来描述实体的类型,在C++中可以用结构来实现封装,但出于跟C语言的兼容一般在C++结构也只封装数据,用class关键字来实现真正的封装,封装后的东西称为类。
*********************封装好的类/结构只是一个类型***************************
定义类:
class xxx{
成员变量或者成员函数的定义
};
结构与类的区别
结构默认情况下就是一个简单打包,内容对外是透明的,可以通过结构变量名访问它的任何一个成员。
类默认是保密封装,对外是不透明的,不允许通过变量直接访问它的成员,除非是故意公开的(public),一般公开的都是函数
这种类或者结构类型的变量(实例)就称之为对象
#include <iostream> using namespace std; struct sDate{//全部成员默认公开 int year; int mouth; int day; void set(int y,int m,int d){ year= y,mouth= m,day=d; } void print(){ cout<<year<<‘-‘<<mouth<<‘-‘<<day<<endl; } }; class cDate{//默认不公开,private int year; int mouth; int day; public: //以下部分公开,若未公开则无法访问 void set(int y,int m,int d){ year= y,mouth= m,day=d; } void print(){ cout<<year<<‘-‘<<mouth<<‘-‘<<day<<endl; } }; int main() { sDate s;//定义对象s cDate c;//定义对象c s.set(2012,12,21);//使用对象 c.set(2016,4,28);//使用对象 s.print(); c.print(); system("pause"); return 0; }
成员函数如果在外面实现(函数体不在这个类的内部),那么函数名应该写成“类名::函数名”。结构也是如此
多文件结构:一个类一般写成一个.h文件和一个.cpp文件,在.h文件中,成员函数只有声明,没有函数体,在.cpp文件中包含.h文件并且给出那些成员函数的定义(包括函数体)
myclass.h:
#ifndef MY_CLASS_DEFANT struct sDate{ int year; int mouth; int day; void set(int y,int m,int d); void print(); }; class cDate{ int year; int mouth; int day; public: //以下部分公开 void set(int y,int m,int d); void print(); }; #endif
myclass.cpp
#include<iostream> using namespace std; #include "myclass.h" void sDate::set(int y,int m,int d){ year= y,mouth= m,day=d; } void sDate::print(){ cout<<year<<‘-‘<<mouth<<‘-‘<<day<<endl; } void cDate::set(int y,int m,int d){ year= y,mouth= m,day=d; } void cDate::print(){ cout<<year<<‘-‘<<mouth<<‘-‘<<day<<endl; }
main.cpp
#include <iostream> using namespace std; #include "myclass.h" int main() { sDate s; cDate c; s.set(2012,12,21); c.set(2016,4,28); s.print(); c.print(); system("pause"); return 0; };
构造函数
创建每一个对象时会自动调用一个成员函数,函数名就是类名,无返回类型。
构造函数可以重载,一般访问限制为公开
#include<iostream> #include <string> using namespace std; class Cat{ public: Cat(){cout<<"call Cat()" <<endl;} Cat(string s) {cout<<s<<"猫闪亮登场!"<<endl;} }; class Dog{ public: Dog(){cout<<"call Dog()" <<endl;} Dog(string s) {cout<<s<<"犬横空出世!"<<endl;} }; int main() { Cat c;//自动调用无参构造函数 Dog d; Cat c2("加菲");//自动调用带string参数的构造函数 Dog d2("贵宾"); Cat c3();// *特别注意* 声明一个函数c3,返回类型Cat,参数表空,并非实例化一个对象 system("pause"); return 0; }