C++深度解析教程笔记9-静态成员变量,静态成员函数,二阶构造,友元,函数重载,操作符重载
C++深度解析教程笔记9
- 第25课 - 类的静态成员变量
- 实验-数对象个数(失败)
- 实验-静态变量
- 小结
- 第26课 - 类的静态成员函数
- 实验-修改对象的静态变量数值
- 实验-利用静态成员函数
- 实验-静态变量+静态函数实现统计对象个数
- 小结
- 第27课 - 二阶构造模式
- 实验-初始化是否成功
- 实验-二阶构造例子
- 实验-二阶构造数组类
- 小结
- 第28课 - 友元的尴尬能力
- 实验-友元
- 实验-友元不具有传递性
- 小结
- 第29课 - 类中的函数重载
- 实验
- 实验
- 实验
- 小结
- 第30课 - 操作符重载的概念
- 实验-友元实现复数相加
- 实验-操作符重载
- 实验
- 小结
- 第31课 - 完善的复数类
- 实验
- 小结
本文学习自狄泰软件学院 唐佐林老师的 C++深度解析教程,图片全部来源于课程PPT,仅用于个人学习记录
第25课 - 类的静态成员变量
成员变量不能在对象间共享,是专属的,可通过对象名访问public成员变量
需求
实验-数对象个数(失败)
#include class Test { private: int mCount; public: Test() : mCount(0) { mCount++; } ~Test() { --mCount; } int getCount() { return mCount; } }; Test gTest; int main() { Test t1; Test t2; printf("count = %d\n", gTest.getCount()); printf("count = %d\n", t1.getCount()); printf("count = %d\n", t2.getCount()); return 0; } /* 期望输出1 2 3,实际输出: count = 1 count = 1 count = 1 */
实验-静态变量
#include class Test { private: static int cCount;//静态 public: Test() { cCount++; } ~Test() { --cCount; } int getCount() { return cCount; } }; int Test::cCount = 0; Test gTest; int main() { Test t1; Test t2; printf("count = %d\n", gTest.getCount()); printf("count = %d\n", t1.getCount()); printf("count = %d\n", t2.getCount()); Test* pt = new Test(); printf("count = %d\n", pt->getCount()); delete pt; printf("count = %d\n", gTest.getCount()); return 0; } /* count = 3 count = 3 count = 3 count = 4 count = 3 */
小结
类中可以通过static关键定义静态成员变量
静态成员变量
第26课 - 类的静态成员函数
问题:不能随时获取当前对象的数据,没有安全性,使用了全局变量
实验-修改对象的静态变量数值
#include class Test { public: static int cCount; public: Test() { cCount++; } ~Test() { --cCount; } int getCount() { return cCount; } }; int Test::cCount = 0; int main() { printf("count = %d\n", Test::cCount);//count = 0 Test::cCount = 1000;//可以修改数值,安全性问题 printf("count = %d\n", Test::cCount);//count = 1000 return 0; }
实验-利用静态成员函数
#include class Demo { private: int i; public: int getI(); static void StaticFunc(const char* s);//静态函数 static void StaticSetI(Demo& d, int v);//静态函数 }; int Demo::getI() { return i; } void Demo::StaticFunc(const char* s) { printf("StaticFunc: %s\n", s); } void Demo::StaticSetI(Demo& d, int v) { d.i = v; } int main() { Demo::StaticFunc("main Begin...");//不需要对象,通过类直接调用 Demo d; Demo::StaticSetI(d, 10); printf("d.i = %d\n", d.getI()); Demo::StaticFunc("main End..."); return 0; } /* StaticFunc: main Begin... d.i = 10 StaticFunc: main End... */
实验-静态变量+静态函数实现统计对象个数
#include class Test { private: static int cCount; public: Test() { cCount++; } ~Test() { --cCount; } static int GetCount() { return cCount; } }; int Test::cCount = 0; int main() { printf("count = %d\n", Test::GetCount()); Test t1; Test t2; printf("count = %d\n", t1.GetCount()); printf("count = %d\n", t2.GetCount()); Test* pt = new Test(); printf("count = %d\n", pt->GetCount()); delete pt; printf("count = %d\n", Test::GetCount()); return 0; } /* count = 0 count = 2 count = 2 count = 3 count = 2 */
小结
第27课 - 二阶构造模式
实验-初始化是否成功
#include class Test { int mi; int mj; bool mStatus;//记录初始化是否成功 public: Test(int i, int j) : mStatus(false) { mi = i; return;//end mj = j; mStatus = true; } int getI() { return mi; } int getJ() { return mj; } int status()//获取状态 { return mStatus; } }; int main() { Test t1(1, 2); // printf("t1.mi = %d\n", t1.getI()); //printf("t1.mj = %d\n", t1.getJ());//不成功 if( t1.status() ) { printf("t1.mi = %d\n", t1.getI()); printf("t1.mj = %d\n", t1.getJ()); } return 0; }
IntArray::IntArray(int len) { //m_pointer = 0;//new int[len];case1 m_pointer = new int[len];//case2 if(m_pointer) { for(int i=0; i m_pointer[i] = 0; } } m_length = len; } int main() { IntArray a(5); a.set(2, 3); printf("%d\n", a.length()); a.free(); return 0; } cyz@cyz-virtual-machine:~/桌面/testcpp$ g++ main.cpp IntArray.cpp cyz@cyz-virtual-machine:~/桌面/testcpp$ ./a.out 段错误 (核心已转储) cyz@cyz-virtual-machine:~/桌面/testcpp$ g++ main.cpp IntArray.cpp cyz@cyz-virtual-machine:~/桌面/testcpp$ ./a.out 5 private: TwoPhaseCons() // 第一阶段构造函数 { //与系统资源无关的初始化 } bool construct() // 第二阶段构造函数 { //与系统资源相关关的初始化 return true; } public: static TwoPhaseCons* NewInstance(); // 对象创建函数 }; TwoPhaseCons* TwoPhaseCons::NewInstance() { TwoPhaseCons* ret = new TwoPhaseCons(); // 若第二阶段构造失败,返回 NULL if( !(ret && ret-construct()) ) { delete ret;//删除半成品 ret = NULL; } return ret; } int main() { TwoPhaseCons* obj = TwoPhaseCons::NewInstance(); printf("obj = %p\n", obj);//obj = 0000000002521CB0 delete obj; return 0; }
实验-二阶构造数组类
//h文件 修改 class IntArray { private: int m_length; int* m_pointer; IntArray(int len) ;// 第一阶段构造函数 bool construct() ;// 第二阶段构造函数 IntArray(const IntArray& obj); public: static IntArray* NewInstance(int length); // 对象创建函数 静态成员函数 //IntArray(int len);//构造函数改为私有 作为第一阶段构造函数 int length(); bool get(int index, int& value); bool set(int index ,int value); ~IntArray(); }; //IntArray.cpp IntArray::IntArray(int len)//第一阶段构造函数 { m_length = len; } bool IntArray::construct() // 第二阶段构造函数 { bool ret=true; m_pointer = new int[m_length]; //与系统资源相关关的初始化 if(m_pointer) { for(int i=0; i m_pointer[i] = 0; } } else { ret=false; } return ret; } IntArray* IntArray::NewInstance(int length)// 对象创建函数 { IntArray* ret = new IntArray(length);//new 第一阶段构造函数 // 若第二阶段构造失败,返回 NULL if( !(ret && ret-construct()) ) { delete ret;//删除半成品 ret = 0; } return ret; } IntArray::~IntArray() { delete[]m_pointer; //printf("~IntArray()\n"); } //main.cpp IntArray* a = IntArray::NewInstance(5); printf("a.length = %d\n", a->length()); a->set(0, 1); for(int i=0; ilength(); i++) { int v = 0; a->get(i, v); printf("a[%d] = %d\n", i, v); } delete a;
小结
第28课 - 友元的尴尬能力
实验-友元
#include #include class Point { double x; double y; public: Point(double x, double y) { this->x = x; this->y = y; } double getX() { return x; } double getY() { return y; } friend double func(Point& p1, Point& p2);//友元 实现访问类 //friend double func(Point& p1, Point& p2);//注释后 error: 'double Point::y' is private within this context }; double func(Point& p1, Point& p2) { double ret = 0; ret = (p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x); ret = sqrt(ret); return ret; } int main() { Point p1(1, 2); Point p2(10, 20); printf("p1(%f, %f)\n", p1.getX(), p1.getY());//p1(1.000000, 2.000000) printf("p2(%f, %f)\n", p2.getX(), p2.getY());//p2(10.000000, 20.000000) printf("|(p1, p2)| = %f\n", func(p1, p2));//|(p1, p2)| = 20.124612 return 0; }
实验-友元不具有传递性
#include class ClassC { const char* n; public: ClassC(const char* n) { this->n = n; } friend class ClassB;//B可以访问C的成员 }; class ClassB { const char* n; public: ClassB(const char* n) { this->n = n; } void getClassCName(ClassC& c) { printf("c.n = %s\n", c.n); } friend class ClassA;//A可以访问B的成员 }; //无传递性,A不可以访问C的成员 class ClassA { const char* n; public: ClassA(const char* n) { this->n = n; } void getClassBName(ClassB& b) { printf("b.n = %s\n", b.n); } /* void getClassCName(ClassC& c)//error: 'const char* ClassC::n' is private within this context { printf("c.n = %s\n", c.n); }*/ }; int main() { ClassA A("A"); ClassB B("B"); ClassC C("C"); A.getClassBName(B);//b.n = B B.getClassCName(C);//c.n = C return 0; }
小结
第29课 - 类中的函数重载
实验
#include class Test { int i; public: Test() { printf("Test::Test()\n"); this->i = 0; } Test(int i) { printf("Test::Test(int i)\n"); this->i = i; } Test(const Test& obj) { printf("Test(const Test& obj)\n"); this->i = obj.i; } static void func() { printf("void Test::func()\n"); } void func(int i) { printf("void Test::func(int i), i = %d\n", i); } int getI() { return i; } }; void func()//全局函数1 { printf("void func()\n"); } void func(int i)//全局函数2 { printf("void func(int i), i = %d\n", i); } int main() { func(); func(1); Test t; // Test::Test() Test t1(1); // Test::Test(int i) Test t2(t1); // Test(const Test& obj) func(); // void func() Test::func(); // void Test::func() func(2); // void func(int i), i = 2; t1.func(2); // void Test::func(int i), i = 2 t1.func(); // void Test::func() return 0; } /* void func() void func(int i), i = 1 Test::Test() Test::Test(int i) Test(const Test& obj) void func() void Test::func() void func(int i), i = 2 void Test::func(int i), i = 2 void Test::func() */
实验
#include #include char* strcpy(char* buf, const char* str, unsigned int n) { return strncpy(buf, str, n); } int main() { const char* s = "D.T.Software"; char buf[8] = {0}; //strcpy(buf, s);//报错,放不下字符串 strcpy(buf, s, sizeof(buf)-1);//利用重载扩展原有函数的功能 printf("%s\n", buf);//D.T.Sof return 0; }
实验
在这里插入代码片
小结
第30课 - 操作符重载的概念
实验-友元实现复数相加
#include class Complex { int a; int b; public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } int getA() { return a; } int getB() { return b; } friend Complex Add(const Complex& p1, const Complex& p2); }; Complex Add(const Complex& p1, const Complex& p2) { Complex ret; ret.a = p1.a + p2.a; ret.b = p1.b + p2.b; return ret; } int main() { Complex c1(1, 2); Complex c2(3, 4); Complex c3 = Add(c1, c2); // c1 + c2 printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());//c3.a = 4, c3.b = 6 return 0; }
实验-操作符重载
#include class Complex { int a; int b; public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } int getA() { return a; } int getB() { return b; } friend Complex operator + (const Complex& p1, const Complex& p2); }; Complex operator + (const Complex& p1, const Complex& p2) { Complex ret; ret.a = p1.a + p2.a; ret.b = p1.b + p2.b; return ret; } int main() { Complex c1(1, 2); Complex c2(3, 4); Complex c3 = operator+(c1, c2); //Complex c3 = c1 + c2; printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());//c3.a = 4, c3.b = 6 return 0; }
实验
#include class Complex { int a; int b; public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } int getA() { return a; } int getB() { return b; } Complex operator + (const Complex& p) { Complex ret; printf("Complex operator + (const Complex& p)\n"); ret.a = this->a + p.a; ret.b = this->b + p.b; return ret; } friend Complex operator + (const Complex& p1, const Complex& p2); }; Complex operator + (const Complex& p1, const Complex& p2) { Complex ret; printf("Complex operator + (const Complex& p1, const Complex& p2)\n"); ret.a = p1.a + p2.a; ret.b = p1.b + p2.b; return ret; } int main() { Complex c1(1, 2); Complex c2(3, 4); Complex c3 = c1 + c2; // c1.operator + (c2) printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0; } /* Complex operator + (const Complex& p) c3.a = 4, c3.b = 6 */ 编译器优先调用类中的函数,其次才是全局函数
小结
第31课 - 完善的复数类
实验
#ifndef _COMPLEX_H_ #define _COMPLEX_H_ class Complex { private: double a; double b; public: Complex(double a=0,double b=0); double getA(); double getB(); double getmodulus(); Complex operator+(const Complex& c); Complex operator-(const Complex& c); Complex operator*(const Complex& c); Complex operator/(const Complex& c); bool operator==(const Complex& c); bool operator!=(const Complex& c); Complex& operator=(const Complex& c); }; #endif // _COMPLEX_H_ #include "Complex.h" #include "math.h" Complex::Complex(double a,double b) { this->a=a; this->b=b; } double Complex::getA() { return a; } double Complex::getB(){ return b; } double Complex::getmodulus() { double res=sqrt(a*a+b*b); return res; } Complex Complex::operator+(const Complex& c) { double na=a+c.a; double nb=b+c.b; Complex res=Complex(na,nb); return res; } Complex Complex::operator-(const Complex& c) { double na=a-c.a; double nb=b-c.b; Complex res=Complex(na,nb); return res; } Complex Complex::operator*(const Complex& c) { double na=a*c.a-b*c.b; double nb=a*c.b+b*c.a; Complex res=Complex(na,nb); return res; } Complex Complex::operator/(const Complex& c) { double m=c.a*c.a+c.b*c.b; double na=(a*c.a+b*c.b)/m; double nb=(-a*c.b+b*c.a)/m; Complex res=Complex(na,nb); return res; } bool Complex::operator==(const Complex& c){ return a==c.a&&b==c.b; } bool Complex::operator!=(const Complex& c) { return !(a==c.a&&b==c.b); } Complex& Complex::operator=(const Complex& c){ if(this!=&c) { a=c.a; b=c.b; } return *this; } //main.cpp #include #include "Complex.h" int main() { Complex a1(1,2); Complex a2(3,4); Complex a3=a1+a2; printf("%f %f\n",a3.getA(),a3.getB()); printf("a3.getmodulus()=%f\n",a3.getmodulus()); a3=a1-a2; printf("a1-a2 %f %f\n",a3.getA(),a3.getB()); a3=a1*a2; printf("a1*a2%f %f\n",a3.getA(),a3.getB()); a3=a1/a2; printf("a1/a2%f %f\n",a3.getA(),a3.getB()); Complex a4=a1; printf("%f %f\n",a4.getA(),a4.getB()); printf("a4==a1 %d a4!=a1 %d\n",a4==a1,a4!=a1); return 0; }
小结
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。