构造函数重载与互调

构造函数可以互调,但不能在函数体内,只能通过初始化列表的形式 构造函数中不要写业务逻辑 析构函数中不要 delete this ,这会导致析构递归,最终导致栈溢出 class Test{ public: Test(int a, int b, int c){ _a = a; _b = b; _c = c; } // 正确 Test(int a, int b):Test(a, b, 100){ } /* // 错误 Test(int a, int b){ _a = a; _b = b; Test(a, b, 100); // 此处只是产生一个临时对象,马上又被释放掉了,没有任何意义 } */ int getA(){ return _a; } int getB(){ return _b; } int getC(){ return _c; } private: int _a; int _b; int _c; }; int main( ) { Test t1(10, 20); cout << t1....

December 28, 2021 · 1 min · Rick Cui

类的成员函数作为回调函数

思路是借助类的静态成员函数 方式一: class A{ public: A(int a){ m_a = a; } void print(){ cout << "m_a = " << m_a << endl; } void setCur(){ s_curA = this; } static void callback(){ s_curA->print(); } private: static A* s_curA; int m_a; }; A* A::s_curA = nullptr; typedef void (*FUN_S)(); void Handle(FUN_S call){ call(); } int main( ) { A a(10), b(20); a.setCur(); Handle(A::callback); b.setCur(); Handle(A::callback); return 0; } 方式二: class A{ public: A(int a){ m_a = a; } void print(){ cout << "m_a = " << m_a << endl; } static void callback(void *a){ ((A*)a)->print(); } private: int m_a; }; typedef void (*FUN)(void *); void Handle(void *a, FUN call){ call(a); } int main( ) { A a(10), b(20); Handle(&a, A::callback); Handle(&b, A::callback); return 0; } 输出:...

December 28, 2021 · 2 min · Rick Cui

类的兼容性原则

父类指针可以new子类对象,子类指针不可以new父类对象,但是可以接收强转的已经存在的父类指针 父类指针指向本类对象,调用的虚函数和普通函数都是自己的 将子类指针指向父类对象,虚函数执行的是父类的,也可以调用子类函数(这种操作是错误的,编译会报错,虽然可通过指针强转,但是不建议这样做,可能会导致未知错误) 父类指针指向子类对象,虚函数执行的是子类的,并且不能调用子类的函数 父类指针与子类指针之间赋值可以理解为指针所指内容的一种浅拷贝 Father *f = (Father*)Child * 子类的虚函数指针覆盖父类的,并且子类特有的函数指针不会拷贝过去 Child *c = (Child*)new Father父类的虚函数指针覆盖子类的,同时也有子类特有的函数指针 class A{ public: void printA(){ cout << "printA()" << endl; } virtual void print(){ cout << "A::print()" << endl; } }; class B:public A{ public: void printB(){ cout << "printB()" << endl; } virtual void print() override{ cout << "B::print() b = " << b << endl; } private: int b; }; int main( ) { // 1、指向自己的类对象(将父类对象赋值给父类指针) A *a = new A; // 1....

December 28, 2021 · 1 min · Rick Cui

构造函数私有

如果类的内部没有专门创建实例的代码,则是无法创建任何实例的 如果父类构造函数设置成了私有的,则子类无法编译,因为在初始化子类时会先执行父类的构造 class A{ public: private: A(int ){ } }; class B:public A{ public: int x; }; int main( ) { B b; b.x = 0; return 0; } 输出: Start prog.cc:19:7: error: call to implicitly-deleted default constructor of 'B' B b; ^ prog.cc:13:9: note: default constructor of 'B' is implicitly deleted because base class 'A' has an inaccessible default constructor class B:public A{ ^ 1 error generated. 1 Finish

December 28, 2021 · 1 min · Rick Cui

定义一个只能在堆上(栈上)生成对象的类

一、只能在堆上 方法:将析构函数设置为私有 原因:C++ 是静态绑定语言,编译器管理栈上对象的生命周期,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性。若析构函数不可访问,则不能在栈上创建对象 class Test { public: void printT(){ cout << "printT" << endl; } void freeT(){ delete this; } private: ~Test(){ cout << "~Test()" << endl; } }; int main( ) { // 不能在栈上创建对象 //Test t; // prog.cc:25:10: error: variable of type 'Test' has private destructor // 只能在堆上创建对象 Test *t = new Test; t->printT(); // 销毁对象 t->freeT(); return 0; } 输出: Start printT ~Test() 0 Finish 二、只能在栈上 方法:将 new 和 delete 重载为私有...

December 27, 2021 · 1 min · Rick Cui