CPP

C++学习笔记

记录一些C++和C的相同与不同之处

Posted by xray1 on October 7, 2019

c++的设计思想可以简单总结面向对象思想和泛型编程(stl)。但其中 c++也兼容了 c的部分语法,在这个总结里面就总结一些 c++c的相同和不同。

输入输出语句

c语言中,使用输入输出语句的时候需要包含头文件 #include<stdio.h>

1
2
3
4
5
6
7
8
Code:

#include<stdio.h>
int main(){
    printf("");
    scanf("%d",&var);
    return 0;
}

而在 c++中,包含了一个全面的标准库(iostream)来提供IO机制,其中定义了四个 IO对象。分别为处理输入的 cinistream类型的对象,处理输出的 coutostream对象。除此之外还有其他两个ostream对象,分别是cerrclog

1
2
3
4
5
6
7
#include<iostream>
int main(){
    std::cout << "" << std::endl;
    int a;
    std::cin >> a;
    return 0;
}

变量和基本类型

除了c语言中的基本类型以后,c++主要的改变有如下这些

const
基本知识
  1. c中,const修饰的变量依然为变量,而在 c++中,const修饰的变量会被转换为常量。
  2. 常量与变量的区别体现在两个方面
    1. 是否可以被用来初始化数组大小
    2. 是否可以被赋值
  3. const类型的对象必须初始化
const与引用
  1. 可以把引用绑定到const对象上,但是对常量的引用不能被用作修改它所绑定的对象。
1
2
3
4
5
Example:
const int ci = 1024;
const int &r1 = ci; // right
r1 = 12; // wrong r1是对常量的引用
int &r2 = ci; //wrong 非常量指针不能指向一个常量对象。

当一个常量引用被绑定到另外一种类型上的过程:

1
2
3
4
5
6
double dval = 3.14;
const int &ri = dval;
======>
const int temp = dval;
const int &ri = temp;

const和指针

四种写法

1
2
3
4
const int * p1; // p1 is a pointer to "int const"/constant ints
int const * p2; // p2 is a pointer to "const"ant ints
int * const p3; // p3 is a "const"ant pointer points to ints
int const * const p4; // p4 is a constant pointer to constant ints
const能不能用做函数签名的一部分

c++中,提供了一种新的函数机制叫做函数重载,简单来讲就是通过相同的函数名但是不同的函数签名可以同时存在于一个工程之中。

1
2
double imag(const double& im) const{...}
double imag(const double im) {...}

以上的两个名字虽然有同样的名字,同样的参数,但是返回值分为const和非const,所以我们可以这两个函数可以使用函数重载。

运算符的优先级

image-20190321154944252

image-20190321155037046

reference

referencec++相对于c中不同的机制。

基本知识
  1. reference的使用方式如下
1
2
int x = 1;
int& a = x;
  1. reference其实就是一个指针,但是是一个不可更改的指针,当它指向一个对象以后就无法再改变。
  2. reference虽然只有指针大小,但是当我们使用sizeof()的时候,它会显示出它所绑定的那个对象大小。
为什么需要使用 pass by reference

因为使用pass by reference时,不需要对函数进行拷贝构造

1
2
3
4
5
6
7
8
void func1(Cls* pobj){ pobj->xxx(); }
void func2(Cls obj){obj.xxx();}
void func3(Cls& obj){ obj.xxx(); }

Cls obj;
func1(&obj);
func2(obj);
func3(obj);

函数

函数基础
  1. 函数可以递归调用,但是不能递归定义。
  2. return语句完成两个动作:1. 返回return语句中的值 2. 将控制权从被调函数转移到主调函数。
  3. 名字有作用域,对象有生命周期。名字的作用域是程序文本的一部分,名字在其中可见。对象的生命周期是程序执行过程中该对象存在的一段时间。
  4. 形参是种自动对象。
局部静态对象 static
  1. 在程序执行路径第一次经过对象定义语句时初始化,并且直到程序终止才被销毁。

  2. 如果局部静态对象没有被初始化,则默认初始化为0

参数传递
  1. 每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化。
  2. 使用引用避免拷贝,当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型函数。
  3. 使用引用形参数返回额外信息。
  4. 顶层constconst int ci当形参有顶层const时,传给它常量对象或者非常量对象又是可以的。
返回类型
  1. 数组不能被拷贝,所以不能使用数组作为返回值。
decltype关键字

decltype(odd) *arrPtr(int i)表示函数返回值是个指针,且指针所指对象与odd类型一致。decltype并不会把数组转换为对应的指针。

函数重载

函数名字相同,但形参列表不同,我们称之为重载函数。

  1. 不允许两个函数除了返回类型,其他所有的要素都相同。
  2. 不能通过传入形参是否为const来区别函数是否重载。
  3. 如果形参时某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载。
  4. const_cast<>将非常量对象转换为常量对象。
函数匹配

这是一个过程,在这个过程中我们把函数的调用与一组重载函数中的某一个关联起来,函数匹配也叫重载确定。

调用重载函数时可能出现的三种结果

  1. 编译器找到一个与实参匹配的函数,并生成调用该函数的代码。
  2. 找不到任何一个函数与实参匹配,此时编译器发出无匹配的错误信息。
  3. 有多于一个函数可以匹配,但是每一个都不是明显的最佳选择,此时也将发生错误,称为二义性调用。