IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 游戏开发之C++对C的扩展(C++基础) -> 正文阅读

[C++知识库]游戏开发之C++对C的扩展(C++基础)

游戏开发之C++对C的扩展(C++)

1.C++的输入和输出

??头文件为iostream,扩展为in out stream,即输入输出流。

//std::cout<<输出内容;
std::endl;//结束标记,通知操作系统立刻输出并换行。
std::cout<<"hello world"<<std::endl;

2.命名空间

2.1 域作用符

主要有以下两点作用

  1. 配合命名空间一起使用
  2. 用户访问相同变量名的全局变量时,可以屏蔽当前作用域的变量名
  3. 可优先识别命名空间外部的函数(需要取消命名空间,让命名空间内部函数名相同的暴露)
//取消命名空间
using namespace A;
namespace A
{
	void Print()
	{
		std::cout << " 命名空间内部print " << std::endl;
	}
}

void Print()
{
	std::cout << " 自定义print " << std::endl;
}

int a = 20;
int main()
{
	int a =100;
	std::cout<< a << std::endl;
	std::cout << ::a << std::endl; // 访问全局变量a
	// 优先识别命名空间外部的函数
	::Print();
	// 如果需要调用命名空间里面的函数,则需要指定域
	A::Print();
	return 0;
}

2.2 C++名字空间

??在c++中,名称(name)可以是符号常量名、变量名、函数名、结构体变量名、枚举类型名、类名和对象名称等等。为了避免名称的冲突(标识符)C++引入命名空间(namespace)。命名空间是为了避免变量名冲突的解决方案。

2.3 命名空间的使用

  1. 声明

namespace [空间名称]
{
定义变量
函数
数据类型
结构体

。。。。。。【代码段】
}
//namespace属于关键字。

  1. 访问

空间名称::成员变量名;
空间名称::成员名称;

namespace [空间名称]{
代码段
}
namespace A
{
    int a =10;
}
namespace B
{
    int a = 20;
}
int main()
{
    std::cout << A::a << std::endl;
    std::cout << B::a << std::endl;
    return 0;
}

2.3.1 命名空间不能嵌套在函数内部

错误写法:

int main()
{
    namespace A
    {
        int a =10;
    }
    namespace B
    {
        int a = 20;
    }
    std::cout << A::a << std::endl;
    std::cout << B::a << std::endl;
    return 0;
}

2.3.2 命名空间可以相互嵌套

// 用户A
namespace A
{
	int a = 10;
	namespace C
	{
		int a;
	}
}


// 用户B
namespace B
{
	int a = 10;

	namespace C
	{
		int a;
	}
}

2.3.3 命名空间可以随时添加扩展

??可以随时把新成员添加进入,不是一定义好便不可更改。

// 用户B
namespace B
{
	int a = 10;

	namespace C
	{
		int a;
	}
}

//对上面的namespace B进行扩展
namespace B
{
	namespace D
	{
		int a;
	}

	void Print()
	{
		std::cout << "namespace B" << std::endl;
	}

}

2.3.4 命名空间可以分离声明和定义

// 命名空间中的函数 定义和声明可以分离
namespace A
{
	void Print();
}

// 分离定义
// 数据类型 空间名称::函数名(参数列表){}
void A::Print()
{
	std::cout << "namespace A" << std::endl;
}

2.3.5 匿名命名空间

??作用跟static类似,只能在本文件中生效。

namespace
{
	void Print()
	{
		std::cout << "  " << std::endl;
	}
}


namespace
{
	void Print1()
	{
		std::cout << " 匿名命名空间1 " << std::endl;
	}
}

2.4 命名空间的取消

TIPS:一定不要随意取消命名空间,因为取消意味着暴露。例如自己定义了一个函数名,一个命名空间暴露了一个函数名与自己定义的相同可能造成不必要的bug。

2.4.1 暴露命名空间的某个变量

using 域名称::描述符;// 声明域中的某一个变量暴露出来
即using 空间名称::变量名或函数名或结构体名称等等;

// 要求直接访问A中的变量a
using A::a;

2.4.2 暴露整个命名空间

using namespace 域名称;// 声明一个命名空间暴露整个空间

//暴露整个A命名空间的所有代码段
using namespace A;

3.严格的类型转换(C++类型转换的增强)

typedef enum
{
	red, blue
}COLOR;

int main(int argc, char** argv)
{
	COLOR color = red;
	color = 1; // 错误
	int* p = malloc(10); // 错误
	char* str = "张三"; //错误
	return 0;
}
// 以上代码在C中是可以运行的在C++中是不可以的,必须要强制类型转换

3.1 数据类型转换的增强

C++中类型转换需要显示声明,比如 void 转 int 需要显示调用(int*)
volatile关键字解析,保持内存可见性(CPU每次处理这个被volatile修饰的变量的时候,都会从内存中重新加载变量的值到寄存器)

  1. static_cast
    用于非多态类型转换(静态转换),任何标准转换都可以使用它,但是不能用于两个完全不相关的类型转换。static_cast转换的时候会进行安全检测,检测两个类型是否为相关类型。
	int i = 10;
	double b = static_cast<double>(i);
	const char* str = "张三";
	int a = static_cast<int>(str); //报错
  1. reinterpret_cast
    将一种类型转换为另一种不同的类型,就是C中的强制类型转换
	int i = 20;
	int* b = reinterpret_cast<int*>(i);
	std::cout << i << " " << b << std::endl;
  1. const_cast
    删除变量const的属性,方便赋值。
	const int i = 3;
	int* p = const_cast<int*>(&i);
	*p = 3;
	std::cout << p << " " << i << std::endl;
  1. dynam_cast
    用于将一个父类对象的指针转换为子类对象的指针或引用。(动态交换)必需包含一个多态类型(虚函数)。
class A { int a; virtual void func() {} };
class B : public A { int b; };
class C :public A { int c; };

int main()
{
	B b;
	A* a = dynamic_cast<B*>(&b);

	if (nullptr == a)
		printf("error\n");
	else
		printf("success\n");

	C* c = dynamic_cast<C*>(a);

	if (nullptr == c)
		printf("error\n");
	else
		printf("success\n");
	return 0;
}

4.结构体的增强

  1. 在C++中,使用结构体不需要添加struct关键字
	struct tempA
	{
		int tempa;
	};

	int main()
	{
		tempA num;
		return 0;
	}
  1. 在C++中,结构体可以有成员变量和成员函数
// 兼容C程序
typedef struct tagA
{
	int a; // 成员变量
	// 成员函数(成员函数可以直接访问成员变量)
	void Print()
	{
		std::cout << "Hello " << a << std::endl;
	}
}TA, * PTA;
  1. 在C++中,结构体可以进行继承
struct A
{
	int a;
	void SetA(int a_)
	{
		a = a_;
	}
};

struct B : A
{
	int b;
	void SetB(int b_)
	{
		b = b_;
	}
};

int main()
{
	A a;
	a.SetA(100);
	printf("%d\n", a.a);
	B b;
	b.SetA(300);
	b.SetB(200);
	printf("%d %d\n", b.a, b.b);
	return 0;
}

5.const的增强

  • 在C中const是一个只读的变量,而在C++中是一个常量,可以当作数组长度使用。
  • C++中const声明的变量没有占用内存,而在C中const需要申请内存。
  • 在C++中尽可能使用const代替宏。

在C++中,常量在编译期间会进行类似于宏替换的操作。
如果对一个常量取地址(或之后对其进行改写),会生成一个临时的内存空间,这个内存空间不会指向该常量。

int main()
{
	 const int *p;//指向一个不可修改的int类型
	 int *const p = (int*)malloc(10);// 表示指针指向的地址不能修改

	const int N = 200;
	int nums[N];//合法

	int* p = (int*)&N;
	*p = 500;
	printf("%d\n", N); // 200
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-18 12:31:35  更:2021-08-18 12:33:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 13:14:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码