大纲:
1.面向对象编程技术概述(基本上就是介绍一下面向对象是什么,所以并没有放进来)
2.c++编程基础
3.函数调用
4.类与对象
5.运算符重载
6.继承与派生
7.多态
8.模板
(才知道代码并不算在字数里面....就这样吧)
//关于类 #includeusing namespace std; class XXX { public: //扔成员函数进来 protected: private: //扔数据成员进来 但某些情况下也会放到别的地方去 };//虽然vs自动识别加上了但也不要忘记这里有个分号!! //1、作用域与可见性相关 extern int a; //假设一个程序里有多个cpp文件 在其他cpp文件中有一个全局对象(如在类外定义的对象)则可以在另外的调用 // int main() { double d = 0.5; cout << "sizeof(bool):" << sizeof(bool) << endl; //输出结果: sizeof(bool):1 int a = 5; { int a = 2; int c = a * 3;//c=6外层被屏蔽 } int c = a * 3;//c=15 } int a = 5;//这是一个全局对象 static int b = 2;//定义静态对象,只能在当前编译单元起作用,其他cpp文件里用extern也无法调用 //一般要先进行初始化 对于函数内部定义的静态对象,初始化只在第一次函数调用时执行 int main1() { { int a = 2; int c1 = a * 3;//c1=6 int c2 = ::a * 3;//c2=15 这个“::”在调用全局对象 } } #define pi 3.14; //#undef pi 取消宏命令 不会考 extern const double p= 3.14; const double c = 1; //这两个都可以表示常量 前者只是符号没有数据类型 可能会出错 所以一般用后者 //如果想在多文件中调用后者必须加extern //声明形式extern const double p; //还有一个volatile语法与const一样.const是告诉编译器‘不要改变我’ volatile是“我可能会改变” //在优化代码时可以防止出现重大错误 //考试大概不会考到捏 //自定义数据类型 //1.枚举 enum Shape{circle=-10,square=0,rectangle=10};//分号!!!建立shaoe数据类型,几个标识符为枚举常量 enum color{black,green,blue=4,yellow,red};//black=0,green=1,yellow=5,red=6 //2.联合 union UnionX { int a; double b; };//定义联合类型 //简而言之就是大家放在同一段内存空间下 空间大小由最大的成员决定 可以是不同数据类型的 int main2() { UnionX A;//建立对象 A.a = 5;//赋值 A.b = 7.6; cout << sizeof(A.a)<<&A.a << endl;//输出字节数以及地址 //sizeof(A.a)=4 //sizeof(A.b)=8 //sizeof(A)=8 } //3.结构struct //可以把有联系的不同数据类型成员放在一起 比如一个学生的姓名 年龄成绩等 //4.类class //上面都是把数据封装在一起 类可以把数据与函数封装在一起 //扩展数据类型 //1.数组 int a[5] = { 1,4,2,6,3 };//a[i](i=0,1,2,3,4) char ch1[3] = {'c', '+', '+'};//分号捏!!! char ch2[3] = "c++";//报错是因为字符串自带一个空符号‘ ’ char ch3[4] = "c++"; char ch4[] = { 'c', '+', '+', ' ' }; //二维数组 //懒得说了 //先列后行 可以省去第一维的数字不可省去第二维 a[][2]相当于矩阵 //ClassX a[2][3] //不可进行直接复制 //大概不会考 如果要用的话考虑vector比较方便 可对数组进行复制 自动调整大小 #include int main3() { vector da(2, 0.5);//两个元素,初值都为0.5 vector db = da; cout << db[0] << endl;//输出第一个元素值 return 0; } //指针(看看看!!!) //指针的值是所指对象地址 //指针本身也是一个对象 占据内存 有自己的名字 值和地址 //要初始化 否则会出错 int a = 102; int* pa = &a;//&a表示地址 一个类型为T*的指针能够保存T类型对象的地址 //*pa = 100; //可以通过pa修改a的值 // !!!在这里对于已经定义的指针pa,*代表的是将pa所指的内容改成100,与上面指向地址的那个*含义不一样!!!!! //ClassX obj; //ClassX* p = &obj; //数组名与指针名经常可以互换使用 int main4() { double d[2] = { 0.5,8.0 };//分号!!! double* p = d;//指针p指向数组d cout << d[0] << *d << *p << p[0] << endl;//输出第一个元素的值 *在定义的时候为指地址 这里仍然是指内容 cout << d[1] << *(d + 1) << *(p + 1) << endl;//输出第二个元素的值 cout << &d[0] << d << p << &p[0] << endl;//输出第一个元素的地址 cout << *(&d[0]) << *(&p[0]) << endl;//输出第一个元素的值 } //如果使用sizeof(指针名),得到的只会是指针本身所占的字节数,而并不是指针所指内存区域的字节数 //sizeod(数组名)得到的就是数组所占内存的字节数 double f1 = 1.8, f2 = 2.8; double* p[2] = { &f1,&f2 }; //指针函数 const int max = 100; //限制指针访问方式变为只读 不可以修改 //常量型指针可以指向常量也可以指向变量 如果指向变量就可以通过指针修改所指变量的值 //引用(类似于别名) 必须初始化 初始化后不能再指代别的对象 但一个对象可以有多次引用 //数据类型& 引用名=被引用的对象名 double d = 0.5; const double& v1 = 1.0; const double& v2 = d; const double& v3 = d + 5.0; //可以加const约束-常引用 常引用可以用常量或者表达式的值初始化 没有约束只能用对象名初始化 //typedef typeid //typedef可以为某种数据类型声明一个新名字 //typeid可以得到一个对象的数据类型 typedef unsigned char uchar;//声明用uchae表示unsigned char //cout< b) ? a : b;//如果前面的表达式为true则赋值a给c 否则给b(咋报错呢 //动态内存分配与释放运算符 //new 建立 delete删除动态对象 T代表数据类型 //T*p1=new T(初值);创建单个对象 使p1指向该对象 // T*p1=new T //delete p1; //T*p2=newT[数组长度]; //delete []p2; 这里有个[]不能少!!! //new建立的堆对象没有名字 只能通过地址进行访问 应用delete释放内存 //名字空间声明 namespace calculator { }//这里可以没有分号 //使用名字空间 //第三章函数 double add(double x, double y);//声明 int func(int a1, int a2) { };//定义 //函数指针 //指针名(实际参数列表) //(*指针名)(实际参数列表) double add(double x, double y) { return(x + y); } double(*fp)(double x, double y) = add;//定义 //fp(1.2, 2.0); 调用 //static函数 //在函数前加上 static这样就在其他编译单元无法调用 //inline函数 //编译时用内嵌函数体的代码代替函数调用语句 inline double add(double x, double y) { return(x+y); } //函数重载 //可以拥有相同的函数名 但是参数列表(参数个数,类型 顺序)需要有所不同 //编译器会根据参数匹配情况自动确定调用哪个函数 //第四章 类与对象 //外界不可访问类的私有成员 class test { void move(int dx, int dy); }; void test::move(int dx, int dy)//函数体部分可以在类内也可以在类外 注意要加类的名称 { } //构造函数 // CPoint d1; // CPoint*p=&d1; // CPoint&d=d1; // d.SetPoint(2,3) //作用是建立类对象时对数据成员初始化 //友元 class teacher { public: teacher(int x = 0, int y = 0) { X = x, Y = y; } friend void show(teacher& t) { cout << t.X << t.Y << endl; } //这里是一个外部函数做友元函数 friend void test::move(teacher& t); //可以声明别的类的函数为友元 friend class test; //可以声明别的类为友元 //!!注意首先这个类里需有teacher类对象 因为teacher类定义在后所以在最开头需要先声明 //class tracher;(像这样 void show() { cout << X << Y << endl; } protected: private: int X, Y; }; //类体外定义 void teacher::show()//成员函数定义 { } void show(teacher&t)//友元函数定义 { } int main5() { teacher d(4, 5); d.show();//调用d的成员函数 show(d);//调用友元函数 } //运算符重载 //重载为!!类!!的成员函数 class Complex { public: Complex(double r = 0, double i = 0); double Getreal() { return real; } double Getimage() { return image; } void Show() const; //流提取 流插入 //重载后可以输入输出类对象数据 friend ostream& operator << (ostream& ost, const Complex& c); friend istream& operator >> (istream& ost, Complex& c); const Complex operator - ();//取负 const Complex operator-(const Complex& c); //默认左操作数为this 所以这也是一个二元减运算符 //如果为友元函数则必须要带齐两个参数 或一个参数(一元运算符) //但一般一元运算符重载为成员函数 二元运算符重载为友元函数 friend const Complex operator-(const Complex& c1, const Complex& c2); friend const Complex operator+(const Complex& c1, const Complex& c2); friend const Complex operator*(const Complex& c1, const Complex& c2); friend const Complex operator/(const Complex& c1, const Complex& c2); //复合赋值运算符 Complex& operator += (const Complex & c); //类型转换运算符 operator int() { return int(real); } //自增 自减 const Complex& operator++(); const Complex operator++(int); //前置 先加1再用 //后置 先用原值再加1 //函数对象(取代函数指针 重载() int operator()(int n1, int n2) { return n1 + n2; }//注意第一个圆括号 代表重载的运算符名 private: double real, image; int value; }; Complex::Complex(double r, double i) { real = r; image = i; } void Complex::Show() const { cout << "(" << real << "," << image << ")" << endl; } const Complex Complex::operator-() { return Complex(-real, -image); } const Complex operator-(const Complex& c1, const Complex& c2) { double r = c1.real - c2.real; double i = c1.image - c2.image; return Complex(r, i);//注意这里的返回值 } Complex& Complex::operator +=(const Complex& c) { real = real + c.real; image = image + c, image; return *this;//注意一下!! } //前置 先加1再用 const Complex& Complex::operator++() { ++value; return *this; } //后置 先用原值再加1 const Complex Complex::operator++ (int) { Complex temp(*this); value++; return temp; } ostream& operator << (ostream& ost, const Complex& c) { ost << "(" << c.real << "," << c.image << ")" << endl; return ost; } istream& operator >> (istream& ist, Complex& c) { cout << "请输入复数,如(2.5,3.5):" << endl; char ch; ist >> ch >> c.real >> ch >> c.image; return ist; } int main6() { Complex c1(3.5, 4.5); Complex a; cout << int(c1) << endl; Complex c; c = -c1; c.Show(); cin >> a; cout << a; } //第六章 继承与派生(看书捏!!) //派生类以public继承 派生类新增加成员可以访问public protected 外界无法直接访问protected //派生类以private继承全部成员属性变成private //派生类以protected继承全部成员属性变成private //private不可以直接访问 // 派生类需要重新定义构造函数和析构函数 // //当派生类重新定义了同名函数时 基类中的同名函数会被屏蔽(调用不出来) //想调用需要 基类名:: 限制 class UnivPerson { public: protected: private: }; class Student :public UnivPerson //派生类定义 { public: private: }; //虚基类 //当基类通过多条派生路径被一个派生类继承时,改派生类只继承该基类一次 class a { void f() {}; }; class :virtual public a { }; //第七章 多态 //静态绑定 在编译阶段 动态绑定 在程序运行时确定 //继承与向上类型转换 //虚函数 //模板 //template //类型 函数模板名(参数列表){....} // // template // T Larger(T x,T y){return(x>y)?x:y;} //Larger (3,4); 调用时用具体类型代替参数类型 //Larger(3,4); //函数模板也可以像普通函数一样进行重载 template<> string Larger (string x1, string x2) { return(x1 > x2) ? x1 : x2; } //类模板的定义与使用 template T Max(T x1,T x2) { return (x1 > x2) ? x1 : x2; } template T Max(T x1, T x2, T x3) { return Max((x1, x2), x3); } template T Max(T* s, int n) { T Max = s[0]; for (int i = 0; i < n; i++) if (s[i] > max)max = s[i]; return max; } int main7() { double a[] = {1.1,4.4 ,2.2 ,8.8 }; cout << Max(a[0], a[1]) << ","; cout << Max(a[0], a[1], a[2]) << ","; cout << Max(a, 4) << endl; char s[] = "c++ Programming."; cout << Max(s, sizeof(s) / sizeof(s[0])) << endl;//输出字符数组中值最大的字符 return 0; } //模板专门化 #include template<> string Larger (string x1,string x2)// 可以省略 { return (x1 > x2) ? x1 : x2; } //没写完捏 看书吧 //类模板 //咋说呢 就像是自己设计一个类似于iostream一样的模板捏 //下面是栈类 还不是类模板 class IntStack { public: IntStack(); void push(const int& element); int pop(); private: enum{size=100}; int stack[size];//存放栈元素的数组 int top;//栈项位置 }; IntStack::IntStack():top(0){ } void IntStack::push(const int& element) { if (top == size) exit(1);//注意这里是括号!! 构造函数 stack[top++] = element; } int IntStack::pop() { if (top == 0)exit(1); return stack[--top]; } //这个才是栈类模板 template //Type为参数类型 class TStack { public: TStack() :top(0) { }//构造函数并初始化栈顶为0 void push(const Type& element); Type pop(); private: enum{size=100}; Type stack[size];//自己定这个栈数组的数据类型 int top; }; //类模板的成员函数如果定义在类外,必须是函数模板的形式 template void TStack ::push(const Type& element) { id(top == size)exit(1); stack[top++] = element; } template Type TStack ::pop() { if (top == 0)exit(1); return stack[--top]; } int main8() { TStack is;//建立栈对象is,Type->int for (int i= 0; i < 10; i++) is.push(i); for (int k = 0; k < 10; k++) cout << is.pop() << ","; TStack ds;//建立另一个栈对象 ds.push(3.14); cout << ds.pop() << endl; return 0; }



