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. RNG vs EDG | SKT vs KTB [20160826]

    G1 RNG:丽桑卓,古拉加斯,强行开团流. EDG:崔斯特,普朗克,伊莉斯游走,全球支援流,小规模团战能以多打少. G2 RNG:塔莉垭,纳尔,烬. EDG:雷克塞,艾克,劫,冲击后排. G3 RN ...

  2. startssl

    Validation Success You have successfully authenticated domain "xxx.com.cn".You will be abl ...

  3. [zhang] ViewController的生命周期分析和使用

    iOS的SDK中提供很多原生ViewController,大大提高了我们的开发效率,下面是我的一些经验. 一.结构 按结构可以对iOS的所有ViewController分成两类:1.主要用于展示内容的 ...

  4. spring mvc定时任务的简单使用

    版权声明:本文为楼主原创文章,未经楼主允许不得转载,如要转载请注明来源. 说起定时任务,开发的小伙伴们肯定不陌生了.有些事总是需要计算机去完成的,而不是傻傻的靠我们自己去.可是好多人对定时器总感觉很陌 ...

  5. 【T电商 3】Nginx的Http(图片)服务器配置+ftp上传使用说明

    在前两篇博客中提到了搭建Nginx和Ftp服务器,在本篇博客,主要是介绍Nginx的配置文件的使用,怎样修改配置文件使其成为一个图片服务器. 一.Nginx图片服务器配置 <span style ...

  6. 浅谈js的键值对key和value

    > 昨晚无意中看到类似下面结构的一段代码的取值问题,引起我的兴趣,花了点时间写了个demo给大家分享一下... var obj = [ {"2011":{"name ...

  7. JS settimeout 使用笔记

    无参数使用方法: setTimeout(function_name,delay_time); 基本使用方法是逗号前是函数名字,不能带有 xxxx(),不然不执行: 但是很多函数都要带参数的,以下是解决 ...

  8. Entity Framwork(EF) 7——在现在数据库的甚而上开发MVC 新项目

    一.开发背景: 由于老系统已经无法满足实际业务需求,需在现有数据库的甚而上开发新的项目. 二.困难点: 而EF默认情况下是要删除现有数据库表格后重新创建,这是不允许的.当你创建数据库对象时系统会提示“ ...

  9. 动态规划 - 最长递增子序列(LIS)

    最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...

  10. Python之路【第十七篇】:Django【进阶篇 】

    Python之路[第十七篇]:Django[进阶篇 ]   Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...