从c面向对象的实现理解c++的对象(二)

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);
}

 

你可能感兴趣的:(C++,面向对象,虚函数)