Unreal Engine 游戏开发学习笔记 20181105


本篇博文实为在”系统”学习 Unreal Engine 4 游戏开发后整理的学习笔记。笔记按照每天的学习内容进行整理记录备忘。

本文为 Week3 Class1! 其中 表示上午的学习内容, 表示下午的学习内容。从本周开始连续三周学习 C++ 基础。同时强烈推荐像我一样的初学者看下”菜鸟教程”的 C++ 部分,本周的笔记绝大部分整理的内容均来自菜鸟笔记,只是内容按照上课老师所讲并在笔记中穿插了一些老师上课所讲实例,感谢菜鸟笔记网站管理员的无私分享。

今日内容摘要(知识点梳理):
上午:

1. 游戏开发工作流程
2. 类 只定义了属性 没有初始值

下午:

3. 构造函数 构造函数实现函数重载 在构造对象时设置及初始化对象属性(属性在类中定义) 构造函数的小括号中可以一条都不写,也可以把所有的属性都进行初始化
4. 析构函数:删除对象释放该对象占用的内存空间 调用构造函数的过程就是构造一个对象至内存中,打死怪物应该从内存中删除!~ Dog(){}
5. 一般一个类里面有: 特征 属性函数 构造函数 析构函数 行为函数
6. struct 结构体:比enum难点儿 比类简单


类和对象

类和对象

C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。
类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。

C++ 类定义

定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。例如,我们使用关键字 class 定义 Box 数据类型,如下所示:

1
2
3
4
5
6
7
class Box
{
public:
double length; // 盒子的长度
double breadth; // 盒子的宽度
double height; // 盒子的高度
};

关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。您也可以指定类的成员为 private 或 protected,这个我们稍后会进行讲解。

定义 C++ 对象

类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。下面的语句声明了类 Box 的两个对象:

1
2
Box Box1;          // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box

访问数据成员

类的对象的公共数据成员可以使用直接成员访问运算符 (.) 来访问。为了更好地理解这些概念,让我们尝试一下下面的实例:

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
#include <iostream>

using namespace std;

class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};

int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
double volume = 0.0; // 用于存储体积

// box 1 详述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;

// box 2 详述
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;

// box 1 的体积
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Box1 的体积:" << volume <<endl;

// box 2 的体积
volume = Box2.height * Box2.length * Box2.breadth;
cout << "Box2 的体积:" << volume <<endl;
return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Box1 的体积:210
Box2 的体积:1560

需要注意的是,私有的成员和受保护的成员不能使用直接成员访问运算符 (.) 来直接访问。我们将在后续的教程中学习如何访问私有成员和受保护的成员。

类 & 对象详解

到目前为止,我们已经对 C++ 的类和对象有了基本的了解。下面的列表中还列出了其他一些 C++ 类和对象相关的概念

类成员函数

类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。
让我们看看之前定义的类 Box,现在我们要使用成员函数来访问类的成员,而不是直接访问这些类的成员:

1
2
3
4
5
6
7
8
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
double getVolume(void);// 返回体积
};

成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。在类定义中定义的成员函数把函数声明为内联的,即便没有使用 inline 标识符。所以您可以按照如下方式定义 Volume() 函数:

1
2
3
4
5
6
7
8
9
10
11
12
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度

double getVolume(void)
{
return length * breadth * height;
}
};

您也可以在类的外部使用范围解析运算符 :: 定义该函数,如下所示:

1
2
3
4
double Box::getVolume(void)
{
return length * breadth * height;
}

在这里,需要强调一点,在 :: 运算符之前必须使用类名。调用成员函数是在对象上使用点运算符(.),这样它就能操作与该对象相关的数据,如下所示:

1
2
3
Box myBox;          // 创建一个对象

myBox.getVolume(); // 调用该对象的成员函数

让我们使用上面提到的概念来设置和获取类中不同的成员的值:

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
#include <iostream>

using namespace std;

class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度

// 成员函数声明
double getVolume(void);
void setLength( double len );
void setBreadth( double bre );
void setHeight( double hei );
};

// 成员函数定义
double Box::getVolume(void)
{
return length * breadth * height;
}

void Box::setLength( double len )
{
length = len;
}

void Box::setBreadth( double bre )
{
breadth = bre;
}

void Box::setHeight( double hei )
{
height = hei;
}

// 程序的主函数
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
double volume = 0.0; // 用于存储体积

// box 1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);

// box 2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);

// box 1 的体积
volume = Box1.getVolume();
cout << "Box1 的体积:" << volume <<endl;

// box 2 的体积
volume = Box2.getVolume();
cout << "Box2 的体积:" << volume <<endl;
return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Box1 的体积: 210
Box2 的体积: 1560

C++ 类访问修饰符

数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符。
一个类可以有多个 public、protected 或 private 标记区域。每个标记区域在下一个标记区域开始之前或者在遇到类主体结束右括号之前都是有效的。成员和类的默认访问修饰符是 private。

1
2
3
4
5
6
7
8
class Base {
public:
// 公有成员
protected:
// 受保护成员
private:
// 私有成员
};

公有(public)成员

公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值,如下所示:

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
#include <iostream>

using namespace std;

class Line
{
public:
double length;
void setLength( double len );
double getLength( void );
};

// 成员函数定义
double Line::getLength(void)
{
return length ;
}

void Line::setLength( double len )
{
length = len;
}

// 程序的主函数
int main( )
{
Line line;

// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

// 不使用成员函数设置长度
line.length = 10.0; // OK: 因为 length 是公有的
cout << "Length of line : " << line.length <<endl;
return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Length of line : 6
Length of line : 10

私有(private)成员

私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。
默认情况下,类的所有成员都是私有的。例如在下面的类中,width 是一个私有成员,这意味着,如果您没有使用任何访问修饰符,类的成员将被假定为私有成员:

1
2
3
4
5
6
7
8
class Box
{
double width;
public:
double length;
void setWidth( double wid );
double getWidth( void );
};

实际操作中,我们一般会在私有区域定义数据,在公有区域定义相关的函数,以便在类的外部也可以调用这些函数,如下所示:

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
#include <iostream>

using namespace std;

class Box
{
public:
double length;
void setWidth( double wid );
double getWidth( void );

private:
double width;
};

// 成员函数定义
double Box::getWidth(void)
{
return width ;
}

void Box::setWidth( double wid )
{
width = wid;
}

// 程序的主函数
int main( )
{
Box box;

// 不使用成员函数设置长度
box.length = 10.0; // OK: 因为 length 是公有的
cout << "Length of box : " << box.length <<endl;

// 不使用成员函数设置宽度
// box.width = 10.0; // Error: 因为 width 是私有的
box.setWidth(10.0); // 使用成员函数设置宽度
cout << "Width of box : " << box.getWidth() <<endl;

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Length of box : 10
Width of box : 10

保护(protected)成员

保护成员变量或函数与私有成员十分相似,但有一点不同,保护成员在派生类(即子类)中是可访问的。
在下一个章节中,您将学习到派生类和继承的知识。现在您可以看到下面的实例中,我们从父类 Box 派生了一个子类 smallBox。
下面的实例与前面的实例类似,在这里 width 成员可被派生类 smallBox 的任何成员函数访问。

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
#include <iostream>
using namespace std;

class Box
{
protected:
double width;
};

class SmallBox:Box // SmallBox 是派生类
{
public:
void setSmallWidth( double wid );
double getSmallWidth( void );
};

// 子类的成员函数
double SmallBox::getSmallWidth(void)
{
return width ;
}

void SmallBox::setSmallWidth( double wid )
{
width = wid;
}

// 程序的主函数
int main( )
{
SmallBox box;

// 使用成员函数设置宽度
box.setSmallWidth(5.0);
cout << "Width of box : "<< box.getSmallWidth() << endl;

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
Width of box : 5

继承中的特点

有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。

  1. public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private
  2. protected 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:protected, protected, private
  3. private 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:private, private, private
    但无论哪种继承方式,上面两点都没有改变:
  4. private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;
  5. protected 成员可以被派生类访问。
public 继承
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
#include<iostream>
#include<assert.h>
using namespace std;

class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正确
cout << a1 << endl; //正确
cout << a2 << endl; //正确
cout << a3 << endl; //正确
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
class B : public A{
public:
int a;
B(int i){
A();
a = i;
}
void fun(){
cout << a << endl; //正确,public成员
cout << a1 << endl; //正确,基类的public成员,在派生类中仍是public成员。
cout << a2 << endl; //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。
cout << a3 << endl; //错误,基类的private成员不能被派生类访问。
}
};
int main(){
B b(10);
cout << b.a << endl;
cout << b.a1 << endl; //正确
cout << b.a2 << endl; //错误,类外不能访问protected成员
cout << b.a3 << endl; //错误,类外不能访问private成员
system("pause");
return 0;
}
protected 继承
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
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正确
cout << a1 << endl; //正确
cout << a2 << endl; //正确
cout << a3 << endl; //正确
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
class B : protected A{
public:
int a;
B(int i){
A();
a = i;
}
void fun(){
cout << a << endl; //正确,public成员。
cout << a1 << endl; //正确,基类的public成员,在派生类中变成了protected,可以被派生类访问。
cout << a2 << endl; //正确,基类的protected成员,在派生类中还是protected,可以被派生类访问。
cout << a3 << endl; //错误,基类的private成员不能被派生类访问。
}
};
int main(){
B b(10);
cout << b.a << endl; //正确。public成员
cout << b.a1 << endl; //错误,protected成员不能在类外访问。
cout << b.a2 << endl; //错误,protected成员不能在类外访问。
cout << b.a3 << endl; //错误,private成员不能在类外访问。
system("pause");
return 0;
}
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = 1;
a2 = 2;
a3 = 3;
a = 4;
}
void fun(){
cout << a << endl; //正确
cout << a1 << endl; //正确
cout << a2 << endl; //正确
cout << a3 << endl; //正确
}
public:
int a1;
protected:
int a2;
private:
int a3;
};
class B : private A{
public:
int a;
B(int i){
A();
a = i;
}
void fun(){
cout << a << endl; //正确,public成员。
cout << a1 << endl; //正确,基类public成员,在派生类中变成了private,可以被派生类访问。
cout << a2 << endl; //正确,基类的protected成员,在派生类中变成了private,可以被派生类访问。
cout << a3 << endl; //错误,基类的private成员不能被派生类访问。
}
};
int main(){
B b(10);
cout << b.a << endl; //正确。public成员
cout << b.a1 << endl; //错误,private成员不能在类外访问。
cout << b.a2 << endl; //错误, private成员不能在类外访问。
cout << b.a3 << endl; //错误,private成员不能在类外访问。
system("pause");
return 0;
}

构造函数 析构函数 拷贝构造函数

C++ 类构造函数

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
下面的实例有助于更好地理解构造函数的概念:

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
#include <iostream>

using namespace std;

class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数

private:
double length;
};

// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}

void Line::setLength( double len )
{
length = len;
}

double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;

// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Object is being created
Length of line : 6

带参数的构造函数

默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值,如下面的例子所示:

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
#include <iostream>

using namespace std;

class Line
{
public:
void setLength( double len );
double getLength( void );
Line(double len); // 这是构造函数

private:
double length;
};

// 成员函数定义,包括构造函数
Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}

void Line::setLength( double len )
{
length = len;
}

double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line(10.0);

// 获取默认设置的长度
cout << "Length of line : " << line.getLength() <<endl;
// 再次设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
3
Object is being created, length = 10
Length of line : 10
Length of line : 6

使用初始化列表来初始化字段

使用初始化列表来初始化字段:

1
2
3
4
Line::Line( double len): length(len)
{
cout << "Object is being created, length = " << len << endl;
}

上面的语法等同于如下语法:

1
2
3
4
5
Line::Line( double len)
{
length = len;
cout << "Object is being created, length = " << len << endl;
}

假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:

1
2
3
4
C::C( double a, double b, double c): X(a), Y(b), Z(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
#include <iostream>

using namespace std;

class Line
{
public:
void setLength( double len );
double getLength( void );
Line(); // 这是构造函数声明
~Line(); // 这是析构函数声明

private:
double length;
};

// 成员函数定义,包括构造函数
Line::Line(void)
{
cout << "Object is being created" << endl;
}
Line::~Line(void)
{
cout << "Object is being deleted" << endl;
}

void Line::setLength( double len )
{
length = len;
}

double Line::getLength( void )
{
return length;
}
// 程序的主函数
int main( )
{
Line line;

// 设置长度
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
3
Object is being created
Length of line : 6
Object is being deleted

C++ 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:

  • 通过使用另一个同类型的对象来初始化新创建的对象。
  • 复制对象把它作为参数传递给函数。
  • 复制对象,并从函数返回这个对象。
    如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:
    1
    2
    3
    classname (const classname &obj) {
    // 构造函数的主体
    }

在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的。

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
#include <iostream>

using namespace std;

class Line
{
public:
int getLength( void );
Line( int len ); // 简单的构造函数
Line( const Line &obj); // 拷贝构造函数
~Line(); // 析构函数

private:
int *ptr;
};

// 成员函数定义,包括构造函数
Line::Line(int len)
{
cout << "调用构造函数" << endl;
// 为指针分配内存
ptr = new int;
*ptr = len;
}

Line::Line(const Line &obj)
{
cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
ptr = new int;
*ptr = *obj.ptr; // 拷贝值
}

Line::~Line(void)
{
cout << "释放内存" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}

void display(Line obj)
{
cout << "line 大小 : " << obj.getLength() <<endl;
}

// 程序的主函数
int main( )
{
Line line(10);

display(line);

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
3
4
5
调用构造函数
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
释放内存

下面的实例对上面的实例稍作修改,通过使用已有的同类型的对象来初始化新创建的对象:

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
#include <iostream>

using namespace std;

class Line
{
public:
int getLength( void );
Line( int len ); // 简单的构造函数
Line( const Line &obj); // 拷贝构造函数
~Line(); // 析构函数

private:
int *ptr;
};

// 成员函数定义,包括构造函数
Line::Line(int len)
{
cout << "调用构造函数" << endl;
// 为指针分配内存
ptr = new int;
*ptr = len;
}

Line::Line(const Line &obj)
{
cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
ptr = new int;
*ptr = *obj.ptr; // 拷贝值
}

Line::~Line(void)
{
cout << "释放内存" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}

void display(Line obj)
{
cout << "line 大小 : " << obj.getLength() <<endl;
}

// 程序的主函数
int main( )
{
Line line1(10);

Line line2 = line1; // 这里也调用了拷贝构造函数

display(line1);
display(line2);

return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

1
2
3
4
5
6
7
8
9
10
调用构造函数
调用拷贝构造函数并为指针 ptr 分配内存
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
释放内存
释放内存

拷贝构造函数的调用时机

对象以值传递的方式传入函数参数

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
class CExample 
{
private:
int a;

public:
//构造函数
CExample(int b)
{
a = b;
cout<<"creat: "<<a<<endl;
}

//拷贝构造
CExample(const CExample& C)
{
a = C.a;
cout<<"copy"<<endl;
}

//析构函数
~CExample()
{
cout<< "delete: "<<a<<endl;
}

void Show ()
{
cout<<a<<endl;
}
};

//全局函数,传入的是对象
void g_Fun(CExample C)
{
cout<<"test"<<endl;
}

int main()
{
CExample test(1);
//传入对象
g_Fun(test);

return 0;
}

调用g_Fun()时,会产生以下几个重要步骤:

  • test对象传入形参时,会先会产生一个临时变量,就叫 C 吧。
  • 然后调用拷贝构造函数把test的值给C。 整个这两个步骤有点像:CExample C(test);
  • 等g_Fun()执行完后, 析构掉 C 对象

拷贝构造函数几个原则

C++ primer p406 :拷贝构造函数是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。当定义一个新对象并用一个同类型的对象对它进行初始化时,将显示使用拷贝构造函数。当该类型的对象传递给函数或从函数返回该类型的对象时,将隐式调用拷贝构造函数。

  • C++支持两种初始化形式:
    拷贝初始化 int a = 5; 和直接初始化 int a(5); 对于其他类型没有什么区别,对于类类型直接初始化直接调用实参匹配的构造函数,拷贝初始化总是调用拷贝构造函数,也就是说:

    1
    2
    A x(2);  //直接初始化,调用构造函数
    A y = x;  //拷贝初始化,调用拷贝构造函数
  • 必须定义拷贝构造函数的情况:
    只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义拷贝构造函数也可以拷贝;有的类有一个数据成员是指针,或者是有成员表示在构造函数中分配的其他资源,这两种情况下都必须定义拷贝构造函数。

  • 什么情况使用拷贝构造函数:
    类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:

    • 一个对象以值传递的方式传入函数体
    • 一个对象以值传递的方式从函数返回
    • 一个对象需要通过另外一个对象进行初始化。

结构体

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
// 结构体与类的异同:1. 结构体中的数据默认是公开的 类是私有的 2.机构体被认为是符合数据类型(若干简单类型的组合) 3. 类被看待为更高级的数据类型会把难度更大的数据用类来处理
// 结构体也是有构造函数的 编译器会自动添加无参构造函数
struct Point
{
float x;
float y;
Point(float NewX, float NewY) {
x = NewX;
y = NewY;
}
};


struct Circular
{
Point Center;
float Radius;
};

// 结构体一般用来保存数据传递数据用
struct Box
{
// 数据
const float PI = 3.141592654f;
float Length;
float Width;
float Height;

// 构造函数
Box() {

}

Box(float NewL,float NewW,float NewH) {
Length = NewL;
Width = NewW;
Height = NewH;

}
// 求体积 功能函数
// 常量函数:函数体内部只是访问数据而没有修改结构体(类)中的数据 在函数头小括号后加入const即常量函数
float GetBoxVolume() const
{
return Length * Width * Height;
}
float GetArea(float Length, float Width) const
{
return Length * Width;
}
};

可能想问吧

今天上午讲解的主要是上午的作业辅导及函数基础,并没有很难,暂时没有想问的!


一起练习吧

写如下类要有以下成员:

类:
玩家
怪物
武器
演员
技能

成员:
属性本身
属性函数
构造函数
复制构造函数
析构含糊
功能函数



上课代码笔记
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// Week3_Class1.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <ostream>

using namespace std;

/*
1. 多人协作面向对象的意义
2. 类
*/

/*
上网 游戏 聊天
// 电脑:上网 游戏 聊天
// 手机:上网 游戏 聊天
// 平板:上网 游戏 聊天
*/
enum EDogType {
Docile,
Ferocious
};

enum EDogBreed {
HerdingDogs, // 牧羊犬
GoldenRetriever, // 金毛
Husky, // 哈士奇
Chihuahua // 吉娃娃
};

enum EColor {
Black,
White,
Yellow
};

// 类是描述具有相同特征和行为的一类事物,类是一种蓝图(设计方案)
// 定义了一个Dog类 告诉编译器什么是Dog
// 类更加倾向于功能行为 构造函数不需要加const
class Dog {
private: // 把属性私有
// 以下都是用来描述够的特征的 形体 性格 品种等
EColor DogColor;
float Height;
float Weight;
EDogType DogType;
string Name;
EDogBreed DogBreed;
float HP;

public:
// 读取数据
EColor GetDogColor() const
{
return DogColor;
}
// 写入数据
void SetDogColor(EColor NewColor) {
DogColor = NewColor;
}
float GetHeight() const
{
return Height;
}
void SetHeight(float NewHeight) {
Height = NewHeight;
}

public: // 公开的 只有加入这个才可以在类的外部调用及访问 把函数公开
// 构造函数:构建(产生)类的一个个体 1.函数定义中没有返回中 2.构造函数的函数名与类名称相同
// 构建函数的作用:1.构建(产生)类的一个个体 2. 初始化对象属性
// 构造函数之间也可有重载关系
Dog(string NewName,EColor NewColor)
{
Name = NewName;
DogColor = NewColor;
cout << "构造函数1调用中..." << endl;
}
Dog(EColor NewColor,EDogBreed NewBreed,float NewHP)
{
DogColor = NewColor;
DogBreed = NewBreed;
HP = NewHP;
cout << "构造函数2调用中..." << endl;
}
Dog(EColor NewColor, EDogBreed NewBreed, float NewHP, string NewName, EDogType NewType)
{
DogColor = NewColor;
DogBreed = NewBreed;
HP = NewHP;
Name = NewName;
DogType = NewType;
cout << "构造函数3调用中..." << endl;
}
// 复制构造函数 默认不写也行
// int a = 5; int* Pa = &a;
// 参数上加& 引用参数
// ADog是常量不允许修改
Dog(const Dog& ADog) {
DogColor = ADog.DogColor;
DogBreed = ADog.DogBreed;
// ADog.DogColor = EColor::Black; //加上const后不能修改 本来也不需要修改就是要他的参数
HP = ADog.HP;
}

// 析构函数 释放对象占用的内存空间
~Dog()
{

}
// 函数用来定义狗的行为
void DestroyHome() {
cout << "真无聊,准备找点儿乐子..." << endl;
}
void Eat() {
cout << "吃了一顿狗粮..." << endl;
}
string Talk() {
return "Good Morning!";
}
void ChangeHP() {

}
};


// 不使用& 拷贝参数 传递的为复制的参数
int Plus(int a, int b) {
a += 1;
cout << "a: " << a << endl;
return a + b;
}
/*
// 使用& 不会拷贝原始数据在调用 会直接修改原值 这里的a,b即为引用参数
int Plus(int& a, int b) {
a += 1;
cout << "a: " << a << endl;
return a + b;
}
*/

// 如此,如果一个类没有些任何的构造函数,编译器会自动添加一个构造函数
class cat {
// 实例化对象一定需要构造函数,下面是编译器自动创建无参构造函数实例
public:
// 无参构造函数
cat() {

}
// 析构函数也可以自动添加 不需要主动调用 系统可以被动调用
~cat()
{

}
};

enum ESex {
Male,
Female
};

class Students {
private:
string Name;
int Age;
int StudentID;
int Score;
ESex Sex;

public:
ESex GetSex() {
return Sex;
}
void SetSex(ESex NewSex) {
Sex = NewSex;
}
int GetAge() {
return Age;
}
void SetAge(int NewAge) {
Age = NewAge;
}

public:
Students(int NewAge, int NewScore) {
Age = NewAge;
Score = NewScore;
}
Students(int NewStudentID, ESex NewSex,string NewName) {
StudentID = NewStudentID;
Sex = NewSex;
Name = NewName;
}
Students(int NewAge, int NewScore,int NewStudentID, ESex NewSex, string NewName) {
Age = NewAge;
Score = NewScore;
StudentID = NewStudentID;
Sex = NewSex;
Name = NewName;
}
public:
// 行为函数
void Eat() {
cout << "吃饱上学..." << endl;
}

};


// 结构体与类的异同:1. 结构体中的数据默认是公开的 类是私有的 2.机构体被认为是符合数据类型(若干简单类型的组合) 3. 类被看待为更高级的数据类型会把难度更大的数据用类来处理
// 结构体也是有构造函数的 编译器会自动添加无参构造函数
struct Point
{
float x;
float y;
Point(float NewX, float NewY) {
x = NewX;
y = NewY;
}
};


struct Circular
{
Point Center;
float Radius;
};

// 结构体一般用来保存数据传递数据用
struct Box
{
// 数据
const float PI = 3.141592654f;
float Length;
float Width;
float Height;

// 构造函数
Box() {

}

Box(float NewL,float NewW,float NewH) {
Length = NewL;
Width = NewW;
Height = NewH;

}
// 求体积 功能函数
// 常量函数:函数体内部只是访问数据而没有修改结构体(类)中的数据 在函数头小括号后加入const即常量函数
float GetBoxVolume() const
{
return Length * Width * Height;
}
float GetArea(float Length, float Width) const
{
return Length * Width;
}
};

class Monster { // Monster 可以看成一个新的数据类型
// 类的属性 :用来描述类的特征
float AP;
float HP;
public:
Monster() // 构造函数:特殊的函数类型 没有返回值 作用:生成一个类的个体函数
{

}
};

class Player {
float AP;
float HP;
public:
Player() //构造函数:特殊的函数类型 没有返回值 作用:生成一个类的个体函数
{

}
};



int week3_class1()
{
int a = 3, b = 5;
Plus(a, b); // 实参 a,b 是复制品
cout << "a: " << a << endl;


Box ABox; // 调用无参的构造函数
ABox.Height = 10.f;
ABox.Length = 5.f;
ABox.Width = 2.f;
ABox.GetBoxVolume();
Box BBox(20.f, 20.f, 20.f);
BBox.GetBoxVolume();

// float aa; // 基础数据类型
// 自定义数据类型
// MyDog 已经是一条有生命的存在的狗了
// 已经调用了构造函数
Dog MyDog(Yellow,EDogBreed::GoldenRetriever,200.f); // 声明一个类就是定义一种新的数据类型
cout << MyDog.Talk() << endl; // 测试狗是可以说话的
MyDog.Eat(); // 凡是没有设置返回值的函数都不能cout,可以将cout 写在函数内部
Dog Little("小黑", EColor::Black);

// 复制构造函数 默认不写也行 上面又加上说明如何运行
Dog MyGoldenDog(MyDog); // 把对象作为参数创建对象 复制构造


// 生成一个玩家
Player YaSe; // Yase 可以看成一个变量
// 生成一个虫子的怪物
Monster SmallBug;
return 0;
}

void zhishidianweek3class1()
{
// 1. 游戏开发工作流程
// 2. 类 只定义了属性 没有初始值
// 3. 构造函数 构造函数实现函数重载 在构造对象时设置及初始化对象属性(属性在类中定义) 构造函数的小括号中可以一条都不写,也可以把所有的属性都进行初始化
// 4. 析构函数:删除对象释放该对象占用的内存空间 调用构造函数的过程就是构造一个对象至内存中,打死怪物应该从内存中删除!~Dog(){}
// 5. 一般一个类里面有: 特征 属性函数 构造函数 析构函数 行为函数
// 6. struct 结构体:比enum难点儿 比类简单

}




我的作业提交
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
// Week3_Class1_Homework.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <ostream>

using namespace std;

enum EAniType {
Walk,
Run,
Jump
};

enum EVFXType {
Explosion,
Fire,
ICE
};

class Player
{

private:
// 玩家属性
string Name;
float HP;
int LV;
EAniType AniType;
EVFXType VFXType;

public:
// 属性函数
EAniType GetAniType() const
{
return AniType;
};

int GetLV() const
{
return LV;
};

void SetAniType(EAniType NewAniType)
{
AniType = NewAniType;
};
void SetLV(int NewLV)
{
LV = NewLV;
};

public:
// 构造函数
Player(string NewName, float NewHP)
{
Name = NewName;
HP = NewHP;
cout << "构造函数函数1调用中..." << endl;
};
Player(string NewName, float NewHP, int NewLV)
{
Name = NewName;
HP = NewHP;
LV = NewLV;
cout << "构造函数函数2调用中..." << endl;
};
Player(string NewName, float NewHP, int NewLV, EAniType NewAniType, EVFXType NewVFXType)
{
Name = NewName;
HP = NewHP;
LV = NewLV;
AniType = NewAniType;
VFXType = NewVFXType;
cout << "构造函数函数3调用中..." << endl;
};
// 复制构造函数
Player(const Player& APlayer) {
AniType = APlayer.AniType;
Name = APlayer.Name;
LV = APlayer.LV;
HP = APlayer.HP;
VFXType = APlayer.VFXType;
cout << "Player类测试复制构造函数...\n" << endl;
}

Player() {

}

// 析构函数
~Player() {

}
public:
// 功能函数
void PlayVFXIce() {
cout << "嚯... 释放冰特效..." << endl;
}
void PlayStats() {
cout << "速度很快,疾跑中..." << endl;
}
string Talking() {
return "Hello,Every One!";
}

};

enum EMonsterType {
Normal,
Hunger,
Mania
};

class Monster
{
private:
// 类属性
int HP;
string Name;
float Speed;
EMonsterType MonsterType;

public:
// 属性函数
EMonsterType GetMonsterType() const
{
return MonsterType;
}
float GetSpeed() const
{
return Speed;
};

void SetSpeed(float NewSpeed)
{
Speed = NewSpeed;
};
void SetHP(int NewHP)
{
HP = NewHP;
};
public:
// 构造函数
Monster(string NewName, float NewSpeed)
{
Name = NewName;
Speed = NewSpeed;
cout << "Monster类构建函数1调取中..." << endl << endl;
};
Monster(int NewHP, float NewSpeed, EMonsterType NewMonsterType)
{
HP = NewHP;
Speed = NewSpeed;
MonsterType = NewMonsterType;
cout << "Monster类构建函数2调取中..." << endl << endl;
};
// 复制构造函数
Monster(const Monster& AMonster)
{
HP = AMonster.HP;
Name = AMonster.Name;
Speed = AMonster.Speed;
MonsterType = AMonster.MonsterType;
cout << "Monster类测试复制构造函数...\n" << endl << endl;
};
Monster() {

};
// 析构函数
~Monster() {

};
public:
// 类行为函数
void Attack() {
cout << "受死吧... 吼哈..." << endl << endl;
}
void ReHP() {
cout << "等我回血完成打死你!!!..." << endl << endl;
}

};

enum EWeaponSize {
Small,
Middle,
Big
};

class Weapon {
private:
// Weapon类属性
EWeaponSize WeaponSize;
string Name;
string Skin;

public:
// 属性函数
string GetName() {
return Name;
};
string GetSkint() {
return Skin;
};
void SetName(string NewName) {
Name = NewName;
cout << "当前武器名称改为: " << Name << endl << endl;
};

public:
// 构造函数
Weapon(string NewName, string NewSkin)
{
Name = NewName;
Skin = NewSkin;

cout << "Weapon构造函数1调用中..." << endl << endl;
};
Weapon(string NewName, string NewSkin, EWeaponSize NewWeaponSize) {
Name = NewName;
Skin = NewSkin;
WeaponSize = NewWeaponSize;
cout << "Weapon构造函数2调用中..." << endl << endl;
};

// 复制构造函数
Weapon(const Weapon& AWeapon) {
Name = AWeapon.Name;
Skin = AWeapon.Skin;

WeaponSize = AWeapon.WeaponSize;
cout << "Weapon复制构造函数..." << endl << endl;
};
Weapon() {

};
// 析构函数
~Weapon() {

};
public:
// Weapo功能函数
void CheckStas() {
cout << "武器检修中,请稍后..." << endl << endl;
};
void AttackString() {
cout << "我闻到了熟悉的神魔气息,待我摧毁一些阻挡..." << endl << endl;
}

};

enum EPerformerType {
Actor,
Actress
};

enum EHairStyle {
LongHair,
CurlyHair,
ShortHair
};

enum ERace {
YellowRace,
WhiteRace,
BlackRace
};

class Performer {
private:
//类属性
string Name;
int Age;
EPerformerType PerformerType;
ERace Race;
EHairStyle HairStyle;

public:
// 属性函数
string GetName() {
return Name;
};
int GetAge() {
return Age;
};
EHairStyle GetHairStyle() {
return HairStyle;
};
void SetHairStyle(EHairStyle NewHairStyle) {
HairStyle = NewHairStyle;
};
void SetAge(int NewAge) {
Age = NewAge;
};
public:
// 构造函数
Performer(string NewName, int NewAge, ERace NewRace) {
Name = NewName;
Age = NewAge;
Race = NewRace;
cout << "Performer构造函数1调用中..." << endl << endl;
};

Performer(string NewName, int NewAge, ERace NewRace, EHairStyle NewHairStyle) {
Name = NewName;
Age = NewAge;
Race = NewRace;
HairStyle = NewHairStyle;
cout << "Performer构造函数2调用中..." << endl << endl;
};
Performer(string NewName, int NewAge, ERace NewRace, EHairStyle NewHairStyle, EPerformerType NewPerformerType) {
Name = NewName;
Age = NewAge;
Race = NewRace;
HairStyle = NewHairStyle;
PerformerType = NewPerformerType;
cout << "Performer构造函数3调用中..." << endl << endl;
};
// 复制构造函数
Performer(const Performer& APerformer) {
Name = APerformer.Name;
Age = APerformer.Age;
Race = APerformer.Race;
HairStyle = APerformer.HairStyle;
PerformerType = APerformer.PerformerType;
cout << "Performer复制构造函数..." << endl << endl;
}
Performer() {

}
// 析构函数
~Performer() {

}
public:
// 功能函数
void PlayGoneWithTheWind()
{
cout << "即将为您演绎经典剧目《乱世佳人》..." << endl << endl;
}
void PlayButterflyLove() {
cout << "即将为您演绎经典剧目《梁山伯与祝英台》..." << endl << endl;
}
void PlayTurandot() {
cout << "即将为您演绎经典剧目《图兰朵》..." << endl << endl;
}

};

enum ESkillName {
KaiGuang,
Fofa
};

class Skill {
private:
// 类属性
ESkillName Name;
int CD;
int HP;
float HIT;

public:
ESkillName GetName() const
{
return Name;
};
float GetHit() const
{
return HIT;
};
void SetName(ESkillName NewName)
{
Name = NewName;
};
void SetCD(int NewCD)
{
CD = NewCD;
};
public:
// 构造函数
Skill(ESkillName NewName, int NewCD, int NewHP)
{
Name = NewName;
CD = NewCD;
HP = NewHP;
cout << "Skill构造函数1调用中..." << endl << endl;
};

Skill(ESkillName NewName, int NewCD, int NewHP, float NewHIT)
{
Name = NewName;
CD = NewCD;
HP = NewHP;
HIT = NewHIT;
cout << "Skill构造函数2调用中..." << endl << endl;
}
// 复制构造函数
Skill(const Skill& ASkill) {
Name = ASkill.Name;
CD = ASkill.CD;
HP = ASkill.HP;
HIT = ASkill.HIT;
cout << "Skill复制构造函数..." << endl << endl;
}
Skill() {

}
// 析构函数
~Skill() {

}
public:
// 功能函数
void ReleaseKaiGuang() {
cout << "释放少林生活技能""开光""..." << endl << endl;
}
void ReleaseFoFa() {
cout << "释放少林生活技能""佛法""..." << endl << endl;
}
};

int main()
{

cout << "=========================================================================================" << endl << endl;
// Player类各类函数调用测试
cout << "Player类各类函数调用测试... " << endl << endl;
Player MyPlayer("张三", 1000.f);
cout << endl;
cout << MyPlayer.Talking() << endl << endl;
MyPlayer.PlayVFXIce();
cout << endl;
Player MySecondPlayer(MyPlayer);

cout << "=========================================================================================" << endl << endl;
// Monster类各类函数调用测试
cout << "Monster类各类函数调用测试... " << endl << endl;
Monster MyMonster("李四", 60.f);
MyMonster.ReHP();
Monster MySecondMonster(MyMonster);

cout << "=========================================================================================" << endl << endl;
// Weapon类各类函数调用测试
cout << "Weapon类各类函数调用测试... " << endl << endl;
Weapon MyWeapon("死神镰刀","神装");
MyWeapon.AttackString();
Weapon MySecondWeapon(MyWeapon);
MySecondWeapon.SetName("Hello"); // 复制的构造函数只能修改属性函数和行为函数,构造函数我们直接用的是拷贝的那个参数



cout << "=========================================================================================" << endl << endl;
// Performer类各类函数调用测试
cout << "Performer类各类函数调用测试... " << endl << endl;
Performer MyPerformer("董洁", 25, ERace::YellowRace,EHairStyle::LongHair);
MyPerformer.PlayButterflyLove();
Performer MySecondPerformer(MyPerformer);

cout << "=========================================================================================" << endl << endl;
// Skill类各类函数调用测试
cout << "Skill类各类函数调用测试... " << endl << endl;
Skill MySkill(ESkillName::Fofa, 60, 100,20.f);
MySkill.ReleaseFoFa();
Skill MySecondSkill(MySkill);
cout << endl;
cout << "=========================================================================================" << endl << endl;


return 0;
};


----------本文结束感谢您的阅读----------

本文标题:Unreal Engine 游戏开发学习笔记 20181105

文章作者:XIANVFX

发布时间:2018年11月05日 - 09:11

最后更新:2019年05月21日 - 09:05

原始链接:www.xianvfx.top/UE4/Training/Week3_CPP2/Unreal_Engine_Learning_Notes_W3_1.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

(*❦ω❦) 感谢您的支持! (*❦ω❦)
0%