HSH's Blogs

  • Home

  • Tags

  • Categories

  • Archives

fmod音频处理

Posted on 2019-03-21 | In C++

项目下载地址:https://www.fmod.com/download

Alt text

Untitled

Posted on 2019-03-21

C++ 模板类

Posted on 2019-03-21 | In C++

C++模板类,相当于Java中的泛型,不过模板类的范围更加广阔,可以使用基本数据类型;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
template<class T>
class A{
public:
A(T t){
this->t = t;
}
protected:
T t;
};

// 继承模板类
class B :public A<int>{
public:
B(int a) :A<int>(a){

}
};

template<class E>
class C :A<int>{
public:
C(E e, int a) :A(a){
this->e = e;
}

protected:
E e;
};

template<class T>
class D :A<T>{
public:
D() :A(10){}

D(T t) :A(t){
}
};

void main(){

A<char*> str("hihi");

B b(10);
C<int> c(10,10);

D<int> d1;

D<int> d2(10);

system("pause");
}

C++ 异常处理

Posted on 2019-03-21 | In C++

异常类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void myThrow(int a, int b){
if (b == 0){
throw "除数为零";
}
}

void myThrow2(int a, int b){
try{
myThrow(1, 0);
}
catch (char *cat){
// 如果函数不想捕获异常,则继续往外抛
throw cat;
}
}

void main(){
try{
int age = 200;
if (age > 100){
throw age;
}
}
// 可以抛出和捕获任意类型的异常
catch (int result){
cout << "age = " << result << endl;
}
// ...可以捕获任意类型的异常(未知异常)
catch (...){
cout << "未知异常" << endl;
}

try{
myThrow2(1, 0);
}
catch (char *cat){
cout << cat << endl;
}

system("pause");
}

声明函数抛出异常:

1
2
3
4
// throw声明函数可能会抛出的异常类型
void myThrow2(int a, int b) throw (char*, int){

}

标准异常、自定义异常

1
2
3
4
5
6
// C++标准异常
void myThrow3(int a, int b){
throw out_of_range("超出范围");

throw invalid_argument("非法参数");
}

自定义异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyException{

};

void myThrow(int a, int b){
if (b == 0){
throw MyException();
}
}

// 继承标准异常
class MyException :public exception{
public:
MyException(char* msg) :exception(msg){}
};

内部类异常

1
2
3
4
5
6
7
8
9
10
11
12
13
class Err{
public:
class MyException2{
public:
MyException2(){}
};
};

void myThrow4(){
// 抛出内部类异常
// 这种写法不一定是命名空间,C++中也是有内部类的
throw Err::MyException2();
}

异常接收

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void main(){
try{
myThrow(1, 0);
}
// 可以通过指针,变量和引用来接收,正确的情况应该是用引用来接收,
// 确保在传递过程中不产生副本
catch (MyException& e){
cout << "MyException" << endl;
}
catch (out_of_range oe){
cout << oe.what() << endl;
}

system("pause");
}

C++/C基础

Posted on 2019-03-16 | Edited on 2019-03-21 | In C++

Android log

1
2
3
#define LOGI(FORMAT, ...)  __android_log_print(ANDROID_LOG_INFO, "HSH_LOG", FORMAT, ##__VA_ARGS__);

LOGI("content:%s", "xxx");

虚继承、虚函数、纯虚函数

Posted on 2019-03-08 | Edited on 2019-03-21 | In C++

虚继承解决同源继承二义性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class A{
public:
char* name;
};

class A1 :public A{

};

class A2 :public A{

};

class B :public A1, public A2{

};

void main(){
B b;
// 报错,存在二意性
b.name = "jack";

// 显式指定父类进行调用
b.A1::name = "rose";
b.A2::name = "jack";
}

通过虚继承,可以确保同源继承,只有一份相同的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A1 :virtual public A{

};

class A2 :virtual public A{

};

void main(){
B b;
// 报错,存在二意性
// 当继承父类为virtual继承时,能够确保不同路径继承来的同名成员只有一份拷贝,解决二义性
b.name = "jack";
}

虚函数实现多态

动态多态:在程序运行期间,决定哪个函数被调用(类似于动态代理)
1,继承
2,父类引用或指针接收子类的对象实例
3,函数重写

静态多态:子类进行方法重载

在Java中,默认情况下,使用父类变量来接收子类实例就能够实现动态多态,但是,C++中,要实现
动态多态,我们必须显式的将父类函数声明为虚函数;

plane.h

1
2
3
4
5
6
7
8
9
#pragma once

class Plane{
public:
// 为了实现动态多态,必须声明为virtual类型
virtual void fly();

virtual void land();
};

plane.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include "plane.h"

#include <iostream>
using namespace std;

void Plane::fly(){
cout << "simple fly" << endl;
}

void Plane::land(){
cout << "simple land" << endl;
}

jet.h

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "plane.h"
#include <iostream>

using namespace std;

class Jet :public Plane{

public:
void fly();

void land();

};

jet.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include "jet.h"

#include <iostream>
using namespace std;

void Jet::fly(){
cout << "jet fly" << endl;
}

void Jet::land(){
cout << "jet land" << endl;
}

dragon.h

1
2
3
4
5
6
7
8
9
#pragma once
#include "plane.h"

class Dragon :public Plane{
public:
void fly();

void land();
};

dragon.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include "dragon.h"

#include <iostream>
using namespace std;

void Dragon::fly(){
cout << "Dragon fly" << endl;
}

void Dragon::land(){
cout << "Dragon land" << endl;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "plane.h"
#include "jet.h"
#include "dragon.h"
// 如果在Java中,则可以通过父类接收子类,并且执行时也是调用实际的子类的内容(也就是多态)
void bizPlay(Plane& p){
p.fly();

p.land();
}

void main(){

Plane p;
bizPlay(p);

// 如果想要子类的函数能够被调用(实现多态),则父类声明函数时,必须声明为虚函数
Jet j;
bizPlay(j);

Dragon d;
bizPlay(d);

system("pause");
}

纯虚函数

1,有纯虚函数的类即抽象类
2,抽象类不能被实例化
3,子类继承抽象类,必须实现父类的纯虚函数,否则子类也是抽象类
作用:为了继承约束,对于子类具体实现是未知的。

纯虚函数在函数声明后面必须增加”=0”,这是与虚函数的区别:

拥有纯虚函数的类是抽象类,是不允许进行实例化的:

1
2
3
4
5
6
7
8
9
class Tet{
public:
virtual void myFun()=0;
};

void main(){
// 实例化将在编译期就报错
Tet t;
}

拥有虚函数的类和普通类并没有太大区别(除了实现多态),不管函数只是头文件声明,还是已经实现了
函数体,都能够被直接实例化。

1
2
3
4
5
6
7
8
9
class Tet{
public:
virtual void myFun();
};

void main(){
// 实例化在编译期没有问题,但是,并没有实现函数体,所以运行期将报错;
Tet t;
}

拥有纯虚函数的类即为抽象类,抽象类是允许有非纯虚函数的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Shape{
public:
// 纯虚函数
// 必须等于0,否则会被解释为函数的头文件函数声明
virtual void sayArea() = 0;

// 和Java一样,抽象类中可以有已经实现的方法
void print(){
cout << "I am print" << endl;
}
};

class Circle :public Shape{
public:
Circle(int r){
this->r = r;
}

void sayArea(){
cout << "Circle Area" << endl;
}
private:
int r;
};

void main(){
// 纯虚函数不能被实例化
//Shape s;
//s.sayArea();

// 子类必须实现抽象父类的方法,才能够被实例化
Circle c(2);
c.sayArea();

system("pause");
}

只包含纯虚函数的类即接口

接口与抽象类,在语法上区别并不是很大,只是逻辑上的划分(C++),可以认为,接口就是只存在
纯虚函数的抽象类。

1
2
3
4
// 可以认为是接口
class Drawable{
virtual void draw() = 0;
};

C++ 继承

Posted on 2019-03-08 | Edited on 2019-03-21 | In C++

继承

继承的作用:解决代码的重用性;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class Human{
public:

Human(char* name, int age){
this->name = name;
this->age = age;
cout << "Human构造函数" << endl;
}

~Human(){
cout << "Human析构函数" << endl;
}

void say(){
cout << "说话:..." << endl;
}

private:
// 子类可以继承使用该权限修饰符下的变量和方法
//protected:
char* name;
int age;

};

class Man:public Human{
public:
// 继承后,子类构造方法,需要给父类初始化
// 注意,对象变量的初始化方式很相近
Man(char* name) :Human(name,12),h("Denny",10){
this->brother = name;

cout << "Man 构造函数" << endl;
}

~Man(){
cout << "Man析构函数" << endl;
}

void chasing(){
cout << "正在泡妞" << endl;
}

// 覆盖父类的方法
// 并非多态中的重写
void say(){
cout << "男人说:..." << endl;
}
private:
char* brother;

Human h;
};

// 创建时,先执行父类构造函数,销毁时,先执行子类析构函数
void func(){
Man man("jack");
}

void main(){
//Man m1("");
//m1.say();

// 子类实例可以赋值给父类对象,指针和引用
//Human h1 = m1;
//Human* h_p = &m1;
//Human& h = m1;

//func();

// 并非Java多态中的那种重写,而只是覆盖
Man m1("");
m1.say(); // 男人说:...
// 通过父类实例来接收,调用时指向的是父类的方法,而非子类的方法,
// 说明并非重写,只是覆盖了
Human h = m1;
h.say(); // 说话:...

// 在没有重写的情况下,子类仍然可以调用父类的方法
m1.Human::say();


system("pause");
}

继承权限组合

父类权限 子类继承方式 子类中 子类外
public public public public
public protected public protected
public private public private

protected public protected protected
protected protected protected protected
protected private protected private

private public private private
private protected private private

多继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Person{
public:
Person(char* name){

}
Person(char*name, int age){}
};

class Citizen{
public:
Citizen(int age){

}

public:

void say(){
cout << "saying..."<< endl;
}
};

class Student:public Person,private Citizen{
public:
// 多继承时,构造函数可以有不同的组合
Student(char*name) :Person(name),Citizen(10){

}
Student(char*name, int age) :Person(name,age), Citizen(age){
say();
}

};

虚继承解决同源继承二义性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class A{
public:
char* name;
};

class A1 :public A{

};

class A2 :public A{

};

class B :public A1, public A2{

};

void main(){
B b;
// 报错,存在二意性
b.name = "jack";

// 显式指定父类进行调用
b.A1::name = "rose";
b.A2::name = "jack";
}

通过虚继承,可以确保同源继承,只有一份相同的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A1 :virtual public A{

};

class A2 :virtual public A{

};

void main(){
B b;
// 报错,存在二意性
// 当继承父类为virtual继承时,能够确保不同路径继承来的同名成员只有一份拷贝,解决二义性
b.name = "jack";
}

模板函数

Posted on 2019-03-08 | Edited on 2019-03-21 | In C++

模板函数采用的是类似于Java中的泛型机制,抽取出共同的业务逻辑,让其适用于不同的数据类型;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
template<typename T>
void mySwap(T &a, T &b){
T temp = a;
a = b;
b = temp;
}

template<typename T,typename Z>
void myCout(T &a, Z &b){
cout << a << endl;
cout << b << endl;
}

void main(){

int a = 1;
int b = 2;

//mySwap<int>(a, b);
mySwap(a, b);

myCout<int, char>(a,b);

system("pause");
}

C++ 友元函数和友元类

Posted on 2019-03-03 | Edited on 2019-03-21 | In C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class A{
// 定义友元函数
// 友元函数只是声明,实现将在类外进行
// 必须传递本类的指针作为参数
friend void accessI(A*p, int a);

// 定义B为友元类,这样B中就可以修改A的私有成员
friend class B;
private:
int i;

public:
void printI(){
cout << i << endl;
}
};

class B{
private:
A a;
public:
void modifyA(){
// B是A的友元类,可以修改A的私有成员
a.i = 10;
}
};

void accessI(A*p, int a){
p->i = a;
}

void main(){
A a;
accessI(&a, 100);
a.printI();

system("pause");
}

在Java中,我们可以通过Class.forName(“com.xxx.xx”)的形式,获取到任何类,并且能够通过
Class访问对应类的任何属性,也就是说,Class实际是Java中所有类的友元类(Java底层是用C和C++实现的)。

C++ 静态成员

Posted on 2019-03-03 | Edited on 2019-03-21 | In C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Car{
public:
char *name;
// 静态变量
static int num;

// 静态函数,不能够访问类的成员变量
static void run(){
cout << "car running." << endl;
}
};

// 静态变量初始化只能在类和函数外边进行
int Car::num = 4;

void main(){
// 初始化后,静态变量才可以使用
Car::num++;
cout << Car::num << endl;

// 调用静态函数
Car::run();

// 通过实例也是可以访问的
Car c;
cout << c.num << endl;
c.run();

system("pause");
}
12…8

黄声焕

71 posts
9 categories
21 tags
© 2019 黄声焕
Powered by Hexo v3.7.1
|
Theme — NexT.Gemini v6.3.0