Android C++ 学习笔记3

第3课_C++高级编程

抽象类概念

虚函数赋值0,这是纯虚函数。一个类里面有纯虚函数的话,这个类就叫做抽象类,这个类就不能够实例化对象了,抽象类是给派生类定义框架的,给使用类的应用程序定义好接口。

15th_abstract

1th
Human.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) = 0; //虚函数赋值0,这是纯虚函数
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	void wearing(void) {cout<<"wear english style"<<endl; }
	void driving(void) {cout<<"drive english car"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	void wearing(void) {cout<<"wear chinese style"<<endl; }
	void driving(void) {cout<<"drive chinese car"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};



int main(int argc, char **argv)
{
	//Human h; 这个编译会出错的,抽象类不能够实例化对象
	Englishman e;
	Chinese c;

	return 0;
}	

在这里插入图片描述

Human2.cpp

在这里插入图片描述

在这里插入图片描述

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) = 0;
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	void wearing(void) {cout<<"wear english style"<<endl; }
	void driving(void) {cout<<"drive english car"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	void wearing(void) {cout<<"wear chinese style"<<endl; }
	//void driving(void) {cout<<"drive chinese car"<<endl; } 如果这里不定义的话,Chinese仍旧是个纯虚函数,main函数里实例化Chinese对象还是会报错
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};

class Guangximan : public Chinese {
	void driving(void) {cout<<"drive guangxi car"<<endl; }
};

int main(int argc, char **argv)
{
	//Human h;
	Englishman e;
	Guangximan g;

	return 0;
}

在这里插入图片描述

抽象类界面

一个好的程序应该怎么写出来?

2th

Chinese.h


#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Chinese{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Chinese.cpp


#include "Chinese.h"

void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Englishman.h


#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Englishman {
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Englishman();
};

#endif

Englishman.cpp

#include "Englishman.h"

void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

main.cpp


#include "Englishman.h"
#include "Chinese.h"

int main(int argc, char **argv)
{
	Englishman e;
	Chinese c;

	e.eating();
	c.eating();
	
	return 0;
}

Makefile

Human: main.o Chinese.o Englishman.o
	g++ -o $@ $^

%.o : %.cpp
	g++ -c -o $@ $<

clean:
	rm -f *.o Human	

在这里插入图片描述

3th
3.1
Chinese.cpp

#include "Chinese.h"

void Chinese::setName(char *name) 
{
	this->name = name;
}

char *Chinese::getName(void) 
{
	return this->name;
}


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Chinese{
private:
	char *name;
public:
	void setName(char *name);
	char *getName(void);
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"

void Englishman::setName(char *name) 
{
	this->name = name;
}

char *Englishman::getName(void) 
{
	return this->name;
}

void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Englishman {
private:
	char *name;
public:
	void setName(char *name);
	char *getName(void);
	void eating(void);
	void wearing(void);
	void driving(void);
	~Englishman();
};

#endif

main.cpp

#include "Englishman.h"
#include "Chinese.h"

int main(int argc, char **argv)
{
	Englishman e;
	Chinese c;

	e.eating();
	c.eating();
	
	return 0;
}

Makefile

Human: main.o Chinese.o Englishman.o
	g++ -o $@ $^

%.o : %.cpp
	g++ -c -o $@ $<

clean:
	rm -f *.o Human	

在这里插入图片描述

3.2

上面程序,Chinese和English类里面有很多是重复的,每次都要定义很麻烦。我们定义一个共同的基类,Humun。

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	
};

#endif

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Englishman();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

main.cpp

#include "Englishman.h"
#include "Chinese.h"

int main(int argc, char **argv)
{
	Englishman e;
	Chinese c;

	e.setName("Bill");
	c.setName("zhangsan");

	e.eating();
	c.eating();
	
	return 0;
}

Makefile

Human: main.o Chinese.o Englishman.o Human.o
	g++ -o $@ $^

%.o : %.cpp
	g++ -c -o $@ $<

clean:
	rm -f *.o Human	

在这里插入图片描述

4th

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	virtual void eating(void){cout<<"use hand to eat"<<endl;} //不声明为虚函数的话,会执行基类里的函数
	virtual void wearing(void){}
	virtual void driving(void){}
	
};

#endif

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Englishman();
};

#endif

main.cpp

#include "Human.h"
#include "Englishman.h"
#include "Chinese.h"

void test_eating(Human *h)
{
	h->eating();
}


int main(int argc, char **argv)
{
	Englishman e;
	Chinese c;

	Human* h[2] = {&e, &c};
	int i;
	for (i = 0; i < 2; i++)
		test_eating(h[i]);//指针数组

	
	
	return 0;
}

Makefile

Human: main.o Chinese.o Englishman.o Human.o
	g++ -o $@ $^

%.o : %.cpp
	g++ -c -o $@ $<

clean:
	rm -f *.o Human	

在这里插入图片描述

5th

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	virtual void eating(void) = 0; //纯虚函数
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	
};

#endif

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Englishman();
};

#endif

main.cpp

#include "Human.h"
#include "Englishman.h"
#include "Chinese.h"

void test_eating(Human *h)
{
	h->eating();
}


int main(int argc, char **argv)
{
	Englishman e;
	Chinese c;

	Human* h[2] = {&e, &c};
	int i;
	for (i = 0; i < 2; i++)
		test_eating(h[i]);

	
	
	return 0;
}

Makefile

Human: main.o Chinese.o Englishman.o Human.o
	g++ -o $@ $^

%.o : %.cpp
	g++ -c -o $@ $<

clean:
	rm -f *.o Human	

在这里插入图片描述

6th

使用动态库

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	virtual void eating(void) = 0;
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	
};

#endif

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Englishman();
};

#endif

main.cpp

#include "Human.h"
#include "Englishman.h"
#include "Chinese.h"

void test_eating(Human *h)
{
	h->eating();
}


int main(int argc, char **argv)
{
	Englishman e;
	Chinese c;

	Human* h[2] = {&e, &c};
	int i;
	for (i = 0; i < 2; i++)
		test_eating(h[i]);

	
	
	return 0;
}

Makefile

Human: main.o libHuman.so
	g++ -o $@ $< -L./ -lHuman

%.o : %.cpp
	g++ -fPIC -c -o $@ $<

libHuman.so : Englishman.o Chinese.o Human.o
	g++ -shared -o $@ $^

clean:
	rm -f *.o Human	

在这里插入图片描述

7th

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	virtual void eating(void) = 0;
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	
};

#endif

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman::Englishman() {}
Englishman::Englishman(char *name, int age, char *address)
{
	setName(name);
	this->age = age;
	memset(this->address, 0, 100);
	strcpy(this->address, address);
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
private:
	char address[100];
	int age;
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	Englishman();
	Englishman(char *name, int age, char *address);
	~Englishman();
};

#endif

main.cpp

#include "Human.h"
#include "Englishman.h"
#include "Chinese.h"

void test_eating(Human *h)
{
	h->eating();
}


int main(int argc, char **argv)
{
	Englishman e("Bill", 10, "sfwqerfsdfas");
	Chinese c;

	Human* h[2] = {&e, &c};
	int i;
	for (i = 0; i < 2; i++)
		test_eating(h[i]);

	
	
	return 0;
}

Makefile

Human: main.o libHuman.so
	g++ -o $@ $< -L./ -lHuman

%.o : %.cpp
	g++ -fPIC -c -o $@ $<

libHuman.so : Englishman.o Chinese.o Human.o
	g++ -shared -o $@ $^

clean:
	rm -f *.o Human	

上面程序,动态库里面的头文件发生变化,那么应用层要重新编译一下,否则会有问题,(实际工作我编译libiotsdk.so也遇到过),有没有办法应用层只包含基类的头文件,派生类随便修改,实现分层,应用层不用每次都重新编译?答案是有的。

在这里插入图片描述

8th

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	virtual void eating(void) = 0;
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	
};

Human& CreateEnglishman(char *name, int age, char *address);
Human& CreateChinese(char *name, int age, char *address);

#endif

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Human& CreateChinese(char *name, int age, char *address)
{
	return *(new Chinese());
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman::Englishman() {}
Englishman::Englishman(char *name, int age, char *address)
{
	setName(name);
	this->age = age;
	memset(this->address, 0, 100);
	strcpy(this->address, address);
}

Human& CreateEnglishman(char *name, int age, char *address)
{
	return *(new Englishman(name, age, address));
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
private:
	char address[100];
	int age;
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	Englishman();
	Englishman(char *name, int age, char *address);
	~Englishman();
};

#endif

main.cpp

#include "Human.h"
//#include "Englishman.h"
//#include "Chinese.h"

void test_eating(Human *h)
{
	h->eating();
}


int main(int argc, char **argv)
{
	Human& e = CreateEnglishman("Bill", 10, "sfwqerfsdfas");
	Human& c = CreateChinese("zhangsan", 11, "beijing");

	Human* h[2] = {&e, &c};
	int i;
	for (i = 0; i < 2; i++)
		test_eating(h[i]);

	
	
	return 0;
}

Makefile

Human: main.o libHuman.so
	g++ -o $@ $< -L./ -lHuman

%.o : %.cpp
	g++ -fPIC -c -o $@ $<

libHuman.so : Englishman.o Chinese.o Human.o
	g++ -shared -o $@ $^

clean:
	rm -f *.o Human	

9th

Human.cpp

#include "Human.h"

void Human::setName(char *name) 
{
	this->name = name;
}

char *Human::getName(void) 
{
	return this->name;
}

Human.h

#ifndef _HUMAN_H
#define _HUMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	char *name;

public:
	void setName(char *name);
	char *getName(void);
	virtual void eating(void) = 0;
	virtual void wearing(void) = 0;
	virtual void driving(void) = 0;
	virtual ~Human() {cout<<"~Human"<<endl;} //不能设置为纯虚函数,派生类也需要实现一个Human虚函数,这样就奇怪了
	
};

Human& CreateEnglishman(char *name, int age, char *address);
Human& CreateChinese(char *name, int age, char *address);

#endif

Chinese.cpp

#include "Chinese.h"


void Chinese::eating(void) 
{ 
	cout<<"use chopsticks to eat"<<endl; 
}

void Chinese::wearing(void) 
{
	cout<<"wear chinese style"<<endl; 
}

void Chinese::driving(void) 
{
	cout<<"drive chinese car"<<endl; 
}

Chinese::~Chinese() 
{ 
	cout<<"~Chinese()"<<endl; 
}

Human& CreateChinese(char *name, int age, char *address)
{
	return *(new Chinese());
}

Chinese.h

#ifndef _CHINESE_H
#define _CHINESE_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Chinese : public Human{
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	virtual ~Chinese();
};

#endif

Englishman.cpp

#include "Englishman.h"


void Englishman::eating(void) 
{ 
	cout<<"use knife to eat"<<endl; 
}

void Englishman::wearing(void) 
{
	cout<<"wear english style"<<endl; 
}

void Englishman::driving(void) 
{
	cout<<"drive english car"<<endl; 
}

Englishman::~Englishman() 
{ 
	cout<<"~Englishman()"<<endl; 
}

Englishman::Englishman() {}
Englishman::Englishman(char *name, int age, char *address)
{
	setName(name);
	this->age = age;
	memset(this->address, 0, 100);
	strcpy(this->address, address);
}

Human& CreateEnglishman(char *name, int age, char *address)
{
	return *(new Englishman(name, age, address));
}

Englishman.h

#ifndef _ENGLISHMAN_H
#define _ENGLISHMAN_H

#include <iostream>
#include <string.h>
#include <unistd.h>

#include "Human.h"

using namespace std;

class Englishman : public Human {
private:
	char address[100];
	int age;
public:
	void eating(void);
	void wearing(void);
	void driving(void);
	Englishman();
	Englishman(char *name, int age, char *address);
	virtual ~Englishman();
};

#endif

main.cpp

#include "Human.h"
//#include "Englishman.h"
//#include "Chinese.h"

void test_eating(Human *h)
{
	h->eating();
}


int main(int argc, char **argv)
{
	Human& e = CreateEnglishman("Bill", 10, "sfwqerfsdfas");
	Human& c = CreateChinese("zhangsan", 11, "beijing");

	Human* h[2] = {&e, &c};
	int i;
	for (i = 0; i < 2; i++)
		test_eating(h[i]);

	delete &e;
	delete &c;
	
	
	return 0;
}

Makefile

Human: main.o libHuman.so
	g++ -o $@ $< -L./ -lHuman

%.o : %.cpp
	g++ -fPIC -c -o $@ $<

libHuman.so : Englishman.o Chinese.o Human.o
	g++ -shared -o $@ $^

clean:
	rm -f *.o Human	

函数模板引入

16th_template

下面这个比较大小的函数,返回值不一样,需要重载成千上万个函数吗?

不需要,可使用函数模板。

max.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
T& mymax(T& a, T& b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


int main(int argc, char **argv)
{
	int ia = 1, ib = 2;
	float fa = 1, fb = 2;
	double da = 1, db = 2;
	
	mymax(ia, ib);
	mymax(fa, fb);
	mymax(da, db);

	return 0;
}

在这里插入图片描述

有一个问题,main函数里如果只定义 int ia = 1, ib = 2; 发现编译的程序大小为9141字节,再加上后面两行的话,编译的程序大小为9231字节,为什么增加了将近一百个字节大小?

在这里插入图片描述

在这里插入图片描述

max2.cpp

在这里插入图片描述

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
T& mymax(T& a, T& b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

void add(int a, int b)
{
	cout<<"add(int a, int b) ="<<(a+b)<<endl;
}

int main(int argc, char **argv)
{
	const int ia = 1;
	const int ib = 2;
	
	mymax(ia, ib);

	int a = 1;
	double b = 2.1;
	add(a, b);//传递的参数和定义的类型不一样,产生一个隐式类型转换,从double转换成int 

	mymax(a, b);//模板函数不支持这种隐式类型转换,编译出错

	return 0;
}

函数模板只支持两种隐式转换

在这里插入图片描述

max3.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;
	

	mymax(ia, ib);

	return 0;
}

在这里插入图片描述

max4.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


template<typename T>
const T* mymax2(const T* a, const T* b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

int main(int argc, char **argv)
{
	char a[]="ab";
	char b[]="cd";
	

	mymax(a, b);  /* T=char[3] */
	mymax2(a, b);

	char a2[]="abc";
	char b2[]="cd";

	//mymax(a2, b2);  /* mymax(char[4], char[3]), 无法推导出T: mymax(char& [4], char& [3]), 因为两个参数类型不一样 */
	mymax2(a2, b2);   /* mymax2(char[4], char[3]), 推导: mymax2(const char *, const char *); */

	return 0;
}

在这里插入图片描述

max5.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


template<typename T>
const T* mymax2(const T* a, const T* b)
{
	cout<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
void test_func(T f)
{
	cout<<__PRETTY_FUNCTION__<<endl;
}

int f1(int a, int b)
{
	return 0;
}

int main(int argc, char **argv)
{
	char a[]="ab";
	char b[]="cd";
	

	mymax(a, b);  /* T=char[3] */
	mymax2(a, b);

	char a2[]="abc";
	char b2[]="cd";

	//mymax(a2, b2);  /* mymax(char[4], char[3]), 无法推导出T: mymax(char& [4], char& [3]), 因为两个参数类型不一样 */
	mymax2(a2, b2);   /* mymax2(char[4], char[3]), 推导: mymax2(const char *, const char *); */

	test_func(f1);
	test_func(&f1);

	return 0;
}

在这里插入图片描述

无论传入&f1和 f1,效果都是一样的,表明f1可以转化成指针。

函数模板重载

在这里插入图片描述

在这里插入图片描述

max6.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


const int& mymax(int& a, int& b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	return 0;
}

在这里插入图片描述

max7.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

#if 0
const int& mymax(int& a, int& b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}
#endif

template<typename T>
const T mymax(T a, T b)
{
	cout<<"4: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	return 0;
}

max8.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}


const int& mymax(int& a, int& b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	int *p1=&ia;
	int *p2=&ib;

	cout<<mymax(p1, p2)<<endl;

	return 0;
}

在这里插入图片描述

max9.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T mymax(T * a, T* b)
{
	cout<<"4: "<<__PRETTY_FUNCTION__<<endl;
	return (*a < *b)? *b : *a;
}


const int& mymax(int& a, int& b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	int *p1=&ia;
	int *p2=&ib;

	cout<<mymax(p1, p2)<<endl;

	return 0;
}

在这里插入图片描述

max10.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

template<typename T>
const T mymax(const T * a, const T* b)
{
	cout<<"4: "<<__PRETTY_FUNCTION__<<endl;
	return (*a < *b)? *b : *a;
}


const int& mymax(int& a, int& b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	int *p1=&ia;
	int *p2=&ib;

	cout<<mymax(p1, p2)<<endl;

	return 0;
}

在这里插入图片描述

max11.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

#if 0
template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}
#endif

template<typename T>
const T mymax(const T * a, const T* b)
{
	cout<<"4: "<<__PRETTY_FUNCTION__<<endl;
	return (*a < *b)? *b : *a;
}


const int& mymax(int& a, int& b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	int *p1=&ia;
	int *p2=&ib;

	cout<<mymax(p1, p2)<<endl;

	return 0;
}

在这里插入图片描述

max12.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

/*
int& max(int& a, int& b)
{
	return (a < b)? b : a;
}

double& max(double& a, double& b)
{
	return (a < b)? b : a;
}

float& max(float& a, float& b)
{
	return (a < b)? b : a;
}
*/

template<typename T>
const T& mymax(const T& a, const T& b)
{
	cout<<"1: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}

#if 0
template<typename T>
const T& mymax(T& a, T& b)
{
	cout<<"2: "<<__PRETTY_FUNCTION__<<endl;
	return (a < b)? b : a;
}
#endif

template<typename T>
const T mymax(T * a, T* b)
{
	cout<<"4: "<<__PRETTY_FUNCTION__<<endl;
	return (*a < *b)? *b : *a;
}


char* mymax(char* a, char* b)
{
	cout<<"3: "<<__PRETTY_FUNCTION__<<endl;
	return strcmp(a, b) < 0? b : a;
}

int main(int argc, char **argv)
{
	int ia = 1;
	int ib = 2;

	cout<<mymax(ia, ib)<<endl;

	int *p1=&ia;
	int *p2=&ib;

	cout<<mymax(p1, p2)<<endl;

	char *str1="hello";
	char *str2="Hellod";

	cout<<mymax(str1, str2)<<endl;
	

	return 0;
}

在这里插入图片描述

类模板

17th_class_template

在这里插入图片描述
在这里插入图片描述

template.cpp

模版,这个字母T表示各种数据类型的集合,统一用一个字母T表示。

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;


template<typename T>
class AAA {
private:
	T t;
public:
	void test_func(const T &t);
	void print(void);
};

template<typename T> void AAA<T>::test_func(const T &t)
{
	this->t = t;
}
template<typename T>
void AAA<T>::print(void)
{
	cout<<t<<endl;
}

int main(int argc, char **argv)
{
	AAA<int> a; //类模板

	a.test_func(1);
	a.print();

	AAA<double> b;

	b.test_func(1.23);
	b.print();

	return 0;
}

在这里插入图片描述

template2.cpp

在这里插入图片描述

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;


template<typename T>
class AAA {
private:
	T t;
public:
	void test_func(const T &t);
	void print(void);
};

template<typename T> void AAA<T>::test_func(const T &t)
{
	this->t = t;
}
template<typename T>
void AAA<T>::print(void)
{
	cout<<t<<endl;
}


template<>
class AAA<int> {
public:
	void test_func_int(const int & t)
	{
		cout<<t<<endl;
	}
	void print_int(void);
};

void AAA<int>::print_int(void)
{
	cout<<"for test"<<endl;
}

int main(int argc, char **argv)
{
	AAA<int> a;

	a.test_func_int(1);
	a.print_int();

	AAA<double> b;

	b.test_func(1.23);
	b.print();

	return 0;
}

在这里插入图片描述

异常

在这里插入图片描述

18th_exception

exception.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

void C()
{
	throw 1;
}

void B()
{
	C();
}

void A()
{
	try {
		B();
	} catch (int i)
	{
		cout<<"catch exception "<<i<<endl;
	}
}


int main(int argc, char **argv)
{
	A();
	return 0;
}

在这里插入图片描述

exception2.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

void C(int i)
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else 
		throw c;
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch exception "<<j<<endl;
	}
}


int main(int argc, char **argv)
{
	int i;
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

参数传入2,程序崩溃了,A函数里捕捉int变量,并没有捕捉double(c函数抛出的是double异常),所以异常退出,我们需要完善捕捉功能代码。

exception3.cpp

完善捕捉功能代码

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

void C(int i)
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else 
		throw c;
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch int exception "<<j<<endl;
	} catch (double d)
	{
		cout<<"catch double exception "<<d<<endl;
	} catch (...){
		cout<<"catch other exception "<<endl;
	}
}


int main(int argc, char **argv)
{
	int i;
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述

exception4.cpp

抛出一个类异常

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

class MyException {
public:
	void what(void) { cout<<"This is MyException"<<endl; }
};


void C(int i)
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else if (i == 3)
		throw c;
	else if (i == 4)
		throw MyException();
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch int exception "<<j<<endl;
	} catch (double d)
	{
		cout<<"catch double exception "<<d<<endl;
	} catch (MyException &e)
	{
		e.what();
	} catch (...){
		cout<<"catch other exception "<<endl;
	}
}


int main(int argc, char **argv)
{
	int i;
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述

exception5.cpp

派生类异常

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

class MyException {
public:
	void what(void) { cout<<"This is MyException"<<endl; }
};

class MySubException : public MyException{
public:
	void what(void) { cout<<"This is MySubException"<<endl; }
};


void C(int i)
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else if (i == 3)
		throw c;
	else if (i == 4)
		throw MyException();
	else if (i == 5)
		throw MySubException();//
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch int exception "<<j<<endl;
	} catch (double d)
	{
		cout<<"catch double exception "<<d<<endl;
	} catch (MySubException &e)//派生类隐式转化为基类对象 	   这个要放到前面,先捕捉小范围的,再捕捉大范围的
	{
		e.what();
	} catch (MyException &e)
	{
		e.what();
	} catch (...){
		cout<<"catch other exception "<<endl;
	}
}


int main(int argc, char **argv)
{
	int i;
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述

exception6.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

class MyException {
public:
	virtual void what(void) { cout<<"This is MyException"<<endl; }// 多态
};

class MySubException : public MyException{
public:
	void what(void) { cout<<"This is MySubException"<<endl; }
};


void C(int i)
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else if (i == 3)
		throw c;
	else if (i == 4)
		throw MyException();
	else if (i == 5)
		throw MySubException();
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch int exception "<<j<<endl;
	} catch (double d)
	{
		cout<<"catch double exception "<<d<<endl;
	} catch (MyException &e)
	{
		e.what();
	} catch (...){
		cout<<"catch other exception "<<endl;
	}
}


int main(int argc, char **argv)
{
	int i;
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述

exception7.cpp

C函数声明可能会扔出哪些异常。

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

class MyException {
public:
	virtual void what(void) { cout<<"This is MyException"<<endl; }
};

class MySubException : public MyException{
public:
	void what(void) { cout<<"This is MySubException"<<endl; }
};


void C(int i) throw(int, double) //运行输入3 4 5 不在声明异常列表里面,程序会崩溃
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else if (i == 3)
		throw c;
	else if (i == 4)
		throw MyException();
	else if (i == 5)
		throw MySubException();
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch int exception "<<j<<endl;
	} catch (double d)
	{
		cout<<"catch double exception "<<d<<endl;
	} catch (MyException &e)
	{
		e.what();
	} catch (...){
		cout<<"catch other exception "<<endl;
	}
}

void my_unexpected_func() 
{
	cout<<"my_unexpected_func"<<endl;
}

void my_terminate_func () { cout<<"my_terminate_func"<<endl; }  


int main(int argc, char **argv)
{
	int i;

	set_unexpected (my_unexpected_func); //自己实现意料之外的异常函数 终止函数
	set_terminate(my_terminate_func);
	
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述
在这里插入图片描述

exception8.cpp

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

using namespace std;

class MyException {
public:
	virtual void what(void) { cout<<"This is MyException"<<endl; }
};

class MySubException : public MyException{
public:
	void what(void) { cout<<"This is MySubException"<<endl; }
};


void C(int i) throw(int, double)
{
	int a = 1;
	double b= 1.2;
	float c = 1.3;

	if (i == 0)
	{
		cout<<"In C, it is OK"<<endl;
	}
	else if (i == 1)
		throw a;
	else if (i == 2)
		throw b;
	else if (i == 3)
		throw c;
	else if (i == 4)
		throw MyException();
	else if (i == 5)
		throw MySubException();
}

void B(int i)
{
	cout<<"call C ..."<<endl;
	C(i);
	cout<<"After call C"<<endl;
}

void A(int i)
{
	try {
		B(i);
	} catch (int j)
	{
		cout<<"catch int exception "<<j<<endl;
	} catch (MyException &e)
	{
		e.what();
	} 
}

void my_unexpected_func() 
{
	cout<<"my_unexpected_func"<<endl;
}

void my_terminate_func () { cout<<"my_terminate_func"<<endl; }  


int main(int argc, char **argv)
{
	int i;

	set_unexpected (my_unexpected_func);
	set_terminate(my_terminate_func);
	
	if (argc != 2)
	{
		cout<<"Usage: "<<endl;
		cout<<argv[0]<<" <0|1|2|3>"<<endl;
		return -1;
	}

	i = strtoul(argv[1], NULL, 0);

	A(i);
	
	return 0;
}

在这里插入图片描述

Android C++高级编程:使用NDK_Onur Cinar, 于红PDF电子书下载 带书签目录 完整版 原书名:Pro Android C++ with the NDK 原出版社: Apress 作者: (美)Onur Cinar 译者: 于红 佘建伟 冯艳红 丛书名: 移动开发经典丛书 出版社:清华大学出版社 ISBN:9787302343011 上架时间:2013-12-30 出版日期:2014 年1月 开本:16开 页码:344 版次:1-1 第1章 Android平台上的C++入门 1 1.1 Microsoft Windows 1 1.1.1 在Windows平台上下载并安装JDK开发包 2 1.1.2 在Windows平台上下载并安装Apache ANT 5 1.1.3 在Windows平台上下载并安装Android SDK 7 1.1.4 在Windows平台上下载并安装Cygwin 8 1.1.5 在Windows平台上下载并安装Android NDK 11 1.1.6 在Windows平台上下载并安装Eclipse 13 1.2 Apple Mac OS X 14 1.2.1 在Mac平台上安装Xcode 14 1.2.2 验证Mac平台的Java开发包 15 1.2.3 验证Mac平台上的Apache ANT 15 1.2.4 验证GNU Make 16 1.2.5 在Mac平台上下载并安装Android SDK 16 1.2.6 在Mac平台上下载并安装Android NDK 18 1.2.7 在Mac平台上下载并安装Eclipse 19 1.3 Ubuntu Linux 20 1.3.1 检查GNU C库版本 20 1.3.2 激活在64位系统上支持32位的功能 21 1.3.3 在Linux平台上下载并安装Java开发工具包(JDK) 21 1.3.4 在Linux平台上下载并安装Apache ANT 22 1.3.5 在Linux平台上下载并安装GNU Make 22 1.3.6 在Linux平台上下载并安装Android SDK 23 1.3.7 在Linux平台上下载并安装Android NDK 24 1.3.8 在Linux平台上下载并安装Eclipse 25 1.4 下载并安装ADT 26 1.4.1 安装Android平台包 29 1.4.2 配置模拟器 30 1.5 小结 33 第2章 深入了解Android NDK 35 2.1 Android NDK提供的组件 35 2.2 Android NDK的结构 36 2.3 以一个示例开始 36 2.3.1 指定Android NDK的位置 37 2.3.2 导入示例项目 37 2.3.3 向项目中添加原生支持 39 2.3.4 运行项目 40 2.3.5 用命令行对项目进行构建 41 2.3.6 检测Android NDK项目的结构 42 2.4 构建系统 42 2.4.1 Android.mk 43 2.4.2 Application.mk 53 2.5 使用NDK-Build脚本 54 2.6 排除构建系统故障 55 2.7 小结 56 第3章 用JNI实现与原生代码通信 57 3.1 什么是JNI 57 3.2 以一个示例开始 57 3.2.1 原生方法的声明 58 3.2.2 加载共享库 58 3.2.3 实现原生方法 59 3.3 数据类型 64 3.3.1 基本数据类型 64 3.3.2 引用类型 64 3.4 对引用数据类型的操作 65 3.4.1 字符串操作 65 3.4.2 数组操作 67 3.4.3 NIO 操作 68 3.4.4 访问域 69 3.4.5 调用方法 71 3.4.6 域和方法描述符 72 3.5 异常处理 75 3.5.1 捕获异常 75 3.5.2 抛出异常 75 3.6 局部和全局引用 76 3.6.1 局部引用 76 3.6.2 全局引用 76 3.6.3 弱全局引用 77 3.7 线程 78 3.7.1 同步 78 3.7.2 原生线程 79 3.8 小结 79 第4章 使用SWIG自动生成JNI代码 81 4.1 什么是SWIG 81 4.2 安装 82 4.2.1 Windows平台上SWIG的安装 82 4.2.2 在Mac OS X下安装 83 4.2.3 在Ubuntu Linux下安装 85 4.3 通过示例程序试用SWIG 86 4.3.1 接口文件 86 4.3.2 在命令行方式下调用SWIG 89 4.3.3 将SWIG集成到Android构建过程中 90 4.3.4 更新Activity 92 4.3.5 执行应用程序 93 4.3.6 剖析生成的代码 93 4.4 封装C语言代码 94 4.4.1 全局变量 94 4.4.2 常量 95 4.4.3 只读变量 96 4.4.4 枚举 97 4.4.5 结构体 100 4.4.6 指针 101 4.5 封装C++代码 101 4.5.1 指针、引用和值 102 4.5.2 默认参数 103 4.5.3 重载函数 104 4.5.4 类 104 4.6 异常处理 106 4.7 内存管理 107 4.8 从原生代码中调用Java 108 4.8.1 异步通信 108 4.8.2 启用Directors 109 4.8.3 启用RTTI 109 4.8.4 重写回调方法 109 4.8.5 更新HelloJni Activity 110 4.9 小结 110 第5章 日志、调试及故障处理 111 5.1 日志 111 5.1.1 框架 111 5.1.2 原生日志API 112 5.1.3 受控制的日志 114 5.1.4 控制台日志 118 5.2 调试 119 5.2.1 预备知识 119 5.2.2 调试会话建立 120 5.2.3 建立调试示例 121 5.2.4 启动调试器 121 5.3 故障处理 126 5.3.1 堆栈跟踪分析 127 5.3.2 对JNI的扩展检查 128 5.3.3 内存问题 130 5.3.4 strace 133 5.4 小结 134 第6章 Bionic API入门 135 6.1 回顾标准库 135 6.2 还有另一个C库 136 6.2.1 二进制兼容性 136 6.2.2 提供了什么 136 6.2.3 缺什么 137 6.3 内存管理 137 6.3.1 内存分配 137 6.3.2 C语言的动态内存管理 138 6.3.3 C++的动态内存管理 139 6.4 标准文件I/O 141 6.4.1 标准流 141 6.4.2 使用流I/O 141 6.4.3 打开流 142 6.4.4 写入流 143 6.4.5 流的读取 145 6.4.6 搜索位置 148 6.4.7 错误检查 149 6.4.8 关闭流 149 6.5 与进程交互 150 6.5.1 执行shell命令 150 6.5.2 与子进程通信 150 6.6 系统配置 151 6.6.1 通过名称获取系统属性值 152 6.6.2 通过名称获取系统属性 152 6.7 用户和组 153 6.7.1 获取应用程序用户和组ID 153 6.7.2 获取应用程序用户名 154 6.8 进程间通信 154 6.9 小结 154 第7章 原生线程 155 7.1 创建线程示例项目 155 7.1.1 创建Android项目 155 7.1.2 添加原生支持 157 7.1.3 声明字符串资源 157 7.1.4 创建简单的用户界面 157 7.1.5 实现Main Activity 159 7.1.6 生成C/C++头文件 162 7.1.7 实现原生函数 163 7.1.8 更新Android.mk构建脚本 165 7.2 Java 线程 165 7.2.1 修改示例应用程序使之能够使用Java线程 165 7.2.2 执行Java Threads示例 166 7.2.3 原生代码使用Java线程的优缺点 167 7.3 POSIX线程 168 7.3.1 在原生代码中使用POSIX线程 168 7.3.2 用pthread_create创建线程 168 7.3.3 更新示例应用程序以使用POSIX线程 169 7.3.4 执行POSIX线程示例 174 7.4 从POSIX线程返回结果 174 7.5 POSIX线程同步 176 7.5.1 用互斥锁同步POSIX线程 176 7.5.2 使用信号量同步POSIX线程 180 7.6 POSIX线程的优先级和调度策略 180 7.6.1 POSIX的线程调度策略 181 7.6.2 POSIX Thread优先级 181 7.7 小结 181 第8章 POSIX Socket API:面向连接的通信 183 8.1 Echo Socket示例应用 183 8.1.1 Echo Android应用项目 184 8.1.2 抽象echo activity 184 8.1.3 echo应用程序字符串资源 188 8.1.4 原生echo模块 188 8.2 用TCP sockets实现面向连接的通信 191 8.2.1 Echo Server Activity的布局 192 8.2.2 Echo Server Activity 193 8.2.3 实现原生TCP Server 194 8.2.4 Echo客户端Activity布局 206 8.2.5 Echo客户端Activity 208 8.2.6 实现原生TCP客户端 210 8.2.7 更新Android Manifest 213 8.2.8 运行TCP Sockets示例 214 8.3 小结 217 第9章 POSIX Socket API:无连接的通信 219 9.1 将UDP Server方法添加到Echo Server Activity中 219 9.2 实现原生UDP Server 220 9.2.1 创建UDP Socket:socket 220 9.2.2 从Socket接收数据报:recvfrom 221 9.2.3 向Socket发送数据报:sendto 223 9.2.4 原生UDP Server方法 224 9.3 将原生UDP Client方法加入Echo Client Activity中 225 9.4 实现原生UDP Client 226 9.5 运行UDP Sockets示例 228 9.5.1 连通UDP的模拟器 228 9.5.2 启动Echo UDP Client 229 9.6 小结 229 第10章 POSIX Socket API:本地通信 231 10.1 Echo Local Activity布局 231 10.2 Echo Local Activity 232 10.3 实现原生本地Socket Server 237 10.3.1 创建本地Socket:socket 237 10.3.2 将本地socket与Name绑定:bind 238 10.3.3 接受本地Socket:accept 240 10.3.4 原生本地Socket Server 240 10.4 将本地Echo Activity添加到Manifest中 242 10.5 运行本地 Sockets示例 243 10.6 异步I/O 243 10.7 小结 244 第11章 支持C++ 245 11.1 支持的C++运行库 245 11.1.1 GAbi++ C++运行库 246 11.1.2 STLport C++运行库 246 11.1.3 GNU STL C++运行库 246 11.2 指定C++运行库 246 11.3 静态运行库与动态运行库 247 11.4 C++异常支持 247 11.5 C++ RTTI支持 248 11.6 C++标准库入门 249 11.6.1 容器 249 11.6.2 迭代器 250 11.6.3 算法 251 11.7 C++运行库的线程安全 251 11.8 C++运行库调试模式 251 11.8.1 GNU STL调试模式 251 11.8.2 STLport调试模式 252 11.9 小结 253 第12章 原生图形API 255 12.1 原生图形API的可用性 255 12.2 创建一个AVI视频播放器 256 12.2.1 将AVILib作为NDK的一个导入模块 256 12.2.2 创建AVI播放器Android应用程序 258 12.2.3 创建AVI Player的Main Activity 258 12.2.4 创建Abstract Player Activity 262 12.3 使用JNI图形API进行渲染 269 12.3.1 启用JNI Graphics API 269 12.3.2 使用JNI Graphics API 270 12.3.3 用Bitmap渲染来更新AVI Player 271 12.3.4 运行使用Bitmap渲染的AVI Player 278 12.4 使用OpenGL ES渲染 279 12.4.1 使用OpenGL ES API 279 12.4.2 启用OpenGL ES 1.x API 279 12.4.3 启用OpenGL ES 2.0 API 280 12.4.4 用OpenGL ES渲染来更新AVI Player 280 12.5 使用原生Window API进行渲染 290 12.5.1 启用原生Window API 290 12.5.2 使用原生Window API 291 12.5.3 用原生window渲染器来更新AVI Player 293 12.5.4 EGL图形库 301 12.6 小结 301 第13章 原生音频API 303 13.1 使用OpenSL ES API 303 13.1.1 与OpenSL ES标准的兼容性 304 13.1.2 音频许可 304 13.2 创建WAVE音频播放器 304 13.2.1 将WAVELib作为NDK导入模块 304 13.2.2 创建WAVE播放器Android应用程序 306 13.2.3 创建WAVE播放器主Activity 306 13.2.4 实现WAVE Aduio播放 310 13.3 运行WAVE Audio Player 327 13.4 小结 328 第14章 程序概要分析和NEON优化 329 14.1 用GNU Profiler度量性能 329 14.1.1 安装Android NDK Profiler 329 14.1.2 启用Android NDK Profiler 330 14.1.3 使用GNU Profiler分析gmon.out文件 331 14.2 使用ARM NEON Intrinsics进行优化 332 14.2.1 ARM NEON技术概述 333 14.2.2 给AVI Player添加一个亮度过滤器 333 14.2.3 为AVI播放器启用Android NDK Profiler 336 14.2.4 AVI Player程序概要分析 337 14.2.5 使用NEON Intrinsics优化Brightness Filter 338 14.3 自动向量化 342 14.3.1 启用自动向量化 343 14.3.2 自动向量化问题的发现和排除 344 14.4 小结 344
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行稳方能走远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值