1. 类就可以看作一个struct,类的方法,可以理解为通过函数指针的方式实现的,类对象分配内存时,只分配成员变量的,函数指针并不需要分配额外的内存保存地址。
2. c++中类的构造函数,就是进行内存分配(malloc),调用构造函数
3. c++中类的析构函数,就时回收内存(free)
4. c++是基于栈和全局数据分配内存的,如果是一个方法内创建的对象,就直接在栈上分配内存了。
专门在克隆时使用的构造函数,是构造拷贝函数,原型时“类名(const 类名&)",避免拷贝整个对象,在传递对象时,改为传递指针,同时将构造拷贝函数设置为私有这样做到强制限制。
5. 成员变量为私有,仅仅时编译时起到保护左右,实际内存模型没有变。
6. 继承是在原有的父类的内存模型上,再添加自己的数据
class="cpp">#include <stdio.h> #include <stdlib.h> class TestClass { public: int a; TestClass() { a = 1; printf("do constructor\n"); } ~TestClass() { printf("do destructor\n"); } TestClass(TestClass &src) { a = src.a; } }; void test(TestClass al) { printf("%d\n", al.a); } void test(TestClass *al) { printf("%d\n", al->a); } int main(void) { TestClass ac; printf("after constructor call\n"); printf("=================================\n"); test(ac); printf("after function call\n"); }
?
7. c++多态的实现方式:虚函数(virtual)+使用对象的指针调用:一个类的virtual函数会被分配一个全局数组,保存他们的地址。所有的这个类的对象共享。
如果是自己模拟实现override,实际就是要调用的实现使用函数指针,子类确定这些函数。
/* * test.cpp * * Created on: 2015年5月24日 * Author: jme */ #include <stdio.h> #include <stdlib.h> // 1. 定义一个函数指针 typedef void (*testFunc)(); class Base { public: testFunc getHandler() { return func; } // 函数指针 testFunc func; }; void funcImpl_1() { printf("funcImpl_1\n"); } void funcImpl_2() { printf("funcImpl_2\n"); } class Sub1: public Base { public: Sub1(){ // 2. 子类设置函数指针值 func = funcImpl_1; } }; class Sub2: public Base { public: Sub2() { this->func = funcImpl_2; } }; int main(void) { Base *baseC; Sub1 *upper = new Sub1(); Sub2 *lower = new Sub2(); baseC = upper; baseC->func(); baseC = lower; baseC->func(); }
?c++的virtual语法:
/* * test.cpp * * Created on: 2015年5月24日 * Author: jme */ #include <stdio.h> #include <stdlib.h> class Base { public: // 如果是 virtual void testFunc(); void testFunc2(); }; class Sub1: public Base { public: Sub1(){ } virtual void testFunc(); void testFunc2(); }; class Sub2: public Base { public: Sub2() { } virtual void testFunc(); void testFunc2(); }; class Sub3: public Base { public: Sub3() { } void testFunc(); void testFunc2(); }; void Base::testFunc() { printf("base testFunc\n"); } void Base::testFunc2() { printf("base testFunc2\n"); } void Sub1::testFunc() { printf("Sub1 testFunc\n"); } void Sub1::testFunc2() { printf("Sub1 testFunc2\n"); } void Sub2::testFunc() { printf("Sub2 testFunc\n"); } void Sub2::testFunc2() { printf("Sub2 testFunc2\n"); } void Sub3::testFunc() { printf("Sub3 testFunc\n"); } void Sub3::testFunc2() { printf("Sub3 testFunc2\n"); } void callWithPointer(Base *baseC) { // 因为定义了虚函数, 同时是指针调用,会查虚表,确定具体的实现函数 baseC->testFunc(); } void callWithoutPointer(Base baseC) { // 虽然定义了虚函数, 但是是直接对象调用懂,不会查虚表。 baseC.testFunc(); } void call2(Base *baseC) { // 静态覆盖的实现,根据具体的类型来确定调用的是父类还是子类的 baseC->testFunc2(); } int main(void) { Sub1 s1; Sub2 s2; Sub3 s3; callWithPointer(&s1); callWithPointer(&s2); callWithPointer(&s3); printf("=================\n"); callWithoutPointer(s1); callWithoutPointer(s2); callWithoutPointer(s3); printf("=================\n"); call2(&s1); call2(&s2); call2(&s3); }
?