1. 类就可以看作一个struct,类的方法,可以理解为通过函数指针的方式实现的,类对象分配内存时,只分配成员变量的,函数指针并不需要分配额外的内存保存地址。
2. c++中类的构造函数,就是进行内存分配(malloc),调用构造函数
3. c++中类的析构函数,就时回收内存(free)
4. c++是基于栈和全局数据分配内存的,如果是一个方法内创建的对象,就直接在栈上分配内存了。
专门在克隆时使用的构造函数,是构造拷贝函数,原型时“类名(const 类名&)",避免拷贝整个对象,在传递对象时,改为传递指针,同时将构造拷贝函数设置为私有这样做到强制限制。
5. 成员变量为私有,仅仅时编译时起到保护左右,实际内存模型没有变。
6. 继承是在原有的父类的内存模型上,再添加自己的数据
#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);
}