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

 

發佈了151 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章