1  原生bool类型

c++里面的bool类型才是真正原生的true和faul,比如常见的大写的“BOOL”,它就不是原生的。

原生的与非原生的bool,它们的区别:

详细说下原生bool与非原生bool之间的差别:

_Bool 这个是c98之后加上的bool类型,和我们原生bool等同。

C++中,建议一直使用原生bool,它是最安全的类型。

补充一点:宏定义一个int类型的bool,之所以这么做,是因为0是false,1是true,在C++中,这种比对是有风险的,可以说是不正确的。


2 头文件的三种标准

在vs2015上默认建立一个项目,VS2015帮我们生成4个文件:

stdafx.h这个是微软给我们的一个大坑。

有可能会导致一个问题:预编译头会导致平台不兼容。

文件后缀cpp和c,编译器会选择不同的编译方式编译。

在以DomainOperatorDemo这个解决方案命名的工程中,生成的DomainOperatorDemo.cpp,有程序员直接改名为main.cpp。告诉别人main方法在这里。

在stdafx.h中,默认包含了3个头文件。我们可以直接在main函数中使用printf()。

其中还包含了tchar.h,这是微软给我们的一个坑,它是windows特定的头文件,它前面有个t,带有很强的平台特性。不要过于依赖这个头文件。

以c++中,stdio.h和cstdio功能一样。

3 补充预编译头:提问stdafx.cpp具体的作用是什么呢?

  可以理解为微软的VC特有的文件,实际上我们可以完全的没有它,直接创建空项目。是给编译器用的,并不是我们所需要的。预编译头,想是给我们一定的便利,但并没有什么卵用。


4  域运算符  

它的作用主要就是来解决一件事:

看示例:

变量不是最终的本质,本质是内存里的表述数据。

作用域访问符::

变量的覆盖原则:就近访问。谁最近,我就去找它。

命名空间与作用域:

  在C语言中,我们了解到,变量的生命周期和作用域,就是看这个变量放在哪,外部的、全局的、局部的,局部的局部的等,在C中对变量的作用域控制力是很弱的。

  所以在C++中,特意加入了一个权限概念:命名空间,加强了作用域的控制。除了全局空间,栈空间,又多了一个自已定义的命名空间。

当域作用符前面为空的时候,表示为全局空间,域作用符前面有名称的,就是命名空间

std是个什么样子的命名空间?看图:

如何自定义一个命名空间:

自定义命名空间除了解决变量重定义的问题,它还有其它的作用吗?答案是有的:工业编程里面,大的项目是很多程序员合作的结果,当另一个伙伴想要访问你一个同名的变量时,命名空间就能很好的分隔区分它们。


5  new&delete    运算符

  前面讲到了全局,讲到了栈,现在说说“堆”:

c中我们学到2个操作函数是 malloc()  和  free()。C++中间添加了new 和 delete ;

#include <iostream>

int main()
{
int *pNum = new int();
std::cout << *pNum; return ;
}

运行:100

在C语言中maloc()一定和free()对应使用,那么C++中也是:new一定对应delete使用。

#include <iostream>

int main()
{
int *pNum = new int();
std::cout << *pNum;
delete pNum;
return ;
}

运行:100

再看:如果new一个数组呢,怎么释放?

#include <iostream>

int main()
{
int *pNum = new int();
std::cout << *pNum; int *pArray = new int[]; delete pNum;
delete[] pArray;
return ;
}

运行:100

注意:new  和  delete  是运算符,它们不是函数。重要的说三遍!老师就在课堂里强调了三次。


 6 什么条件下能够构成重载

看代码,我们在C中是这么写函数的:

#include <cstdio>

void MyCoutInt(int num)
{
printf("%d", num);
} void MyCoutChar(char c)
{
printf("%c",c);
} void MyCoutFloat(float f)
{
printf("%f",f);
} void MyCoutString(char *str)
{
printf("%s", str);
} int main()
{ return ;
}

以上在C中,各个函数因为参数不同,而函数名也要不同,不然就重定义了。C++中,可以这样子写:

#include <cstdio>

void MyCout(int num)
{
printf("%d", num);
} void MyCout(char c)
{
printf("%c",c);
} void MyCout(float f)
{
printf("%f",f);
} void MyCout(char *str)
{
printf("%s", str);
} int main()
{ return ;
}

以C++方式编译:通过~!没有问题!    以前C中是完全不能够的,因为函数名重复了。

改成C方式编译:

#include <stdio.h>

void MyCout(int num)
{
printf("%d", num);
} void MyCout(char c)
{
printf("%c",c);
} void MyCout(float f)
{
printf("%f",f);
} void MyCout(char *str)
{
printf("%s", str);
} int main()
{ return ;
}

编译:

1>------ 已启动生成: 项目: OverloadeDemo, 配置: Debug Win32 ------
1> main.c
1>e:\c_code\overloadedemo\overloadedemo\main.c(9): error C2084: 函数“void MyCout(int)”已有主体
1> e:\c_code\overloadedemo\overloadedemo\main.c(3): note: 参见“MyCout”的前一个定义
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

改回C++模式,编译就通过,这个例子引入C++的一个机制:重载

重载——允许函数名相同,但后面的参数一定是不同的。如果函数名相同,参数也相同,就不能构成重载:

#include <cstdio>

void MyCout(int num)
{
printf("%d", num);
} void MyCout(int num)
{
printf("%d", num);
} void MyCout(char c)
{
printf("%c",c);
} void MyCout(float f)
{
printf("%f",f);
} void MyCout(char *str)
{
printf("%s", str);
} int main()
{ return ;
}

编译:

1>------ 已启动生成: 项目: OverloadeDemo, 配置: Debug Win32 ------
1> main.cpp
1>e:\c_code\overloadedemo\overloadedemo\main.cpp(9): error C2084: 函数“void MyCout(int)”已有主体
1> e:\c_code\overloadedemo\overloadedemo\main.cpp(3): note: 参见“MyCout”的前一个定义
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

讲了半天,重载会有什么好处?

#include <cstdio>

void MyCout(int num)
{
printf("%d", num);
} void MyCout(char c)
{
printf("%c",c);
} void MyCout(float f)
{
printf("%f",f);
} void MyCout(char *str)
{
printf("%s", str);
} int main()
{
int num = ;
char c = 'a';
char *str = "I Love Mark";
float f = 1.0002;
MyCout(f);
MyCout(str);
MyCout(num); return ;
}

下断点,运行:

1.000200I Love Mark100

看下C++中cout里面运算符的重载:

再看重载的具体原理,它具体的原理是什么;它里面有些什么潜规则呢?
下个断点,看看重载函数调用的顺序:

看跳转到哪:

其实本质上,C++最终还是生成了4个函数,表面上函数名一样,其本内里是不一样的4个函数。在调用这个函数的时候,编译器会帮我们选择一一对应的函数。根据函数的参数去匹配。

用反汇编查看调用匹配:

充分说明了,内里是不同的,不是表面上看到的一样的。

为什么编译器能给我们一一对应匹配呢?

因为编译器根据符号表里函数名,参数类型,域空间,等元素的不同来重定向函数名:

我们可以假设内里重载的函数名会改名:函数名@类型@类@命名空间……比如:?GetArryLens@MyString@@QAEIXZ

c++里面增加针对函数重载的“命名重定向”与“命名粉碎”的说法:你实际存在符号表里的函数名,被加了参数类型等附加名。这里就有一个问题:

名称被重定向了,命名粉碎了,内里名称已经被更改了,这时当别人调用这个函数的时候,名称已经不是这个我们命名名称了,这里如果别人想要你真实的函数名,会很困扰,这时应该怎么办?这个时候可以加一个前缀extern c :可以使用extern"c"(c编译模式)阻止命名粉碎。

在C中,没有命名粉碎这一概念的。

上面重载都讲参数类型的不同,同名函数重载,那如果这个函数的返回值不同,会不会影响重载失败呢?

重载与否跟返回值没关系,只与函数名和参数有关系:

看测试代码 :

#include <cstdio>

void MyCout(int num)
{
printf("%d\n", num);
} void MyCout(char c)
{
printf("%c\n",c);
} void MyCout(float f)
{
printf("%f\n",f);
}
//MyCout@char* //假设按命名重定向,命名为MyCout@char*
void MyCout(char *str)
{
printf("%s\n", str);
}
//MyCout@char*   //这里也是一样,生成和上面同名了。     
int MyCout(char *str)
{
printf("%s\n", str);
return ;
} int main()
{
int num = ;
char c = 'a';
char *str = "I Love Mark";
float f = 1.0002;
MyCout(f);
MyCout(str);
MyCout(num); return ;
}

编译:报错!

1>------ 已启动生成: 项目: OverloadeDemo, 配置: Debug Win32 ------
1> main.cpp
1>e:\c_code\overloadedemo\overloadedemo\main.cpp(24): error C2556: “int MyCout(char *)”: 重载函数与“void MyCout(char *)”只是在返回类型上不同
1> e:\c_code\overloadedemo\overloadedemo\main.cpp(18): note: 参见“MyCout”的声明
1>e:\c_code\overloadedemo\overloadedemo\main.cpp(23): error C2371: “MyCout”: 重定义;不同的基类型
1> e:\c_code\overloadedemo\overloadedemo\main.cpp(18): note: 参见“MyCout”的声明
1>e:\c_code\overloadedemo\overloadedemo\main.cpp(34): warning C4305: “初始化”: 从“double”到“float”截断
1>e:\c_code\overloadedemo\overloadedemo\main.cpp(36): error C2264: “MyCout”: 函数定义或声明中有错误;未调用函数
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

命名重定向时,不考虑返回值,关键是参数的类型,参数的多少。重定向没有重名就能重载。

#include <cstdio>

void MyCout(int num)
{
printf("%d\n", num);
} void MyCout(char c)
{
printf("%c\n",c);
} void MyCout(float f)
{
printf("%f\n",f);
}
//MyCout@char*
void MyCout(char *str)
{
printf("%s\n", str);
}
//MyCout@char*@int
int MyCout(char *str,int num)
{
printf("%s\n", str);
return ;
} int main()
{
int num = ;
char c = 'a';
char *str = "I Love Mark";
float f = 1.0002;
MyCout(f);
MyCout(str);
MyCout(num); return ;
}

编译通过。

只要最终命名粉碎后,没有重命名,则能构成重载。

PoEdu - C++阶段班- Lesson02_C to C++的更多相关文章

  1. PoEdu - C++阶段班【Po学校】- Lesson03-4_构造函数&赋值函数&拷贝构造函数&学习方式 - 第6天

    PoEdu - C++阶段班[Po学校]- 第6天 课堂选择题目: 1  关于转换构造函数  ClassDemo demo = 1;  调用转换构造函数 2  关于拷贝赋值函数  demo =2; 首 ...

  2. PoEdu - C++阶段班【Po学校】- Lesson02_类与对象_第4天

    复习:上节作业讲解 注意点: 设计SetString()的时候,要注意重置原来的空间. char * SetString(const char *str) { _len = strlen(str); ...

  3. PoEdu - C++阶段班【Po学校】- 第3天

    引用 C中指针的功能强大,使用起来繁杂,因为指针要控制的东西太多:有指针的类型,指针的解引用,指针空间内的值,它本身是有空间的,有自己的地址等.指针也是强大的,比如:我们要在函数之内,修改方法之外的值 ...

  4. PoEdu - C++阶段班- Lesson07 To Lesson10_C to C++

    07  重载导致的二义性 问题:为什么一定要重载呢?重载能方便我们注重函数的功能,当参数类型不确定时,我们能很便捷的利用重载的机制达到目的. 重载注意点:二义性 看代码: #include <c ...

  5. PoEdu - C++阶段班【Po学校】- 第1课

    1 C++开讲 C ++  伟大的编程语言:能提高程序运行效率,节约更多的资源,"正确的使用C++,能够抑制全球变暖问题". 2 C++能力雷达图 通过 1效率 2灵活度 3 抽象 ...

  6. PoEdu- C++阶段班【Po学校】-Lesson03_构造函数精讲 - 第5天

    复习构造函数:1  与类同名   2  没有返回值   3  自动生成    4  手动后,不会自动生成    5  不在特定的情况下,不会私有  新建 类   两种方法示范   其一:在vs中选择类 ...

  7. PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天

    PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数    1  构造  2  析构   3  赋值  4 拷贝构造  5 oper ...

  8. [福大软工] Z班 团队Beta阶段成绩汇总

    Beta敏捷冲刺得分 队伍名 1 2 3 4 5 总分 Dipper 10 10 10 10 10 50 SWSD 9 9 9 9 7 43 五成胜算 10 10 10 10 10 50 人月神教 0 ...

  9. 福州大学软件工程1816 | W班 团队Alpha阶段成绩汇总排名(第9、10次作业)

    写在前面 汇总成绩排名链接 1.作业链接 第九次作业--项目Alpha冲刺(团队) 第十次作业--事后诸葛亮(团队) 2.评分准则 本次作业包括现场Alpha答辩评分(映射总分为100分)+博客分(总 ...

随机推荐

  1. python中利用logging包进行日志记录时的logging.level设置选择

    之前在用python自带的logging包进行日志输出的时候发现有些logging语句没有输出,感到比较奇怪就去查了一下logging文档.然后发现其在设置和引用时的logging level会影响最 ...

  2. Json操作(DynamicJson)

    Json的简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了 ...

  3. CentOS 7 yum安装Zabbix

    一.Zabbix简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案.zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统 ...

  4. 【知识点】业务连接服务(BCS)认证概念整理

    业务连接服务(BCS)认证概念整理 I. BDC认证模型 BDC服务支持两种认证模型:信任的子系统,模拟和代理. 在信任的子系统模型中,中间层(通常是Web服务器)通过一个固定的身份来向后端服务器取得 ...

  5. CyclicBarrier类合唱演绎

    package a.jery; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorServi ...

  6. SSH框架流程

    流程图 具体步骤 一.实体类 //Serializable在网络的环境下做类传输public class Category implements Serializable { private Inte ...

  7. nginx的Location的总结以及rewrite规则的总结

    Location的语法: location 有”定位”的意思, 根据Uri来进行不同的定位. 在虚拟主机的配置中,是必不可少的,location可以把网站的不同部分,定位到不同的处理方式上. 比如,  ...

  8. Oracle SQL: TO_CHAR and TO_NUMBER 笔记

    (1)select TO_CHAR(123.56,'999.9') from dual; will return 123.6select TO_NUMBER('123.56','999.9') fro ...

  9. HashSet中的元素必须重写equals方法和hashCode方法

    http://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html 1.为什么必须重写这两个方法. 2.什么事hashSet去重,符合什么样的 ...

  10. 样式link属性media用法--媒体类型查询

    引用外部样式使用link 你可能想针对将要显示页面的设备类型(桌面PC.笔记本电脑.平板电脑.手机或者甚至页面的印刷版本)来调整页面的样式,可以利用一个media属性, 在<link>元素 ...