C++:相对于C的C++基本特性

从C到C++

本文介绍从C语言过渡到C++的一些基本语法或特性
C++与C是两种语言,
C++没有完全兼容C,所有C代码在 cpp 文件中表示的是另外一种含义,只是表现得符合C的行为
在 cpp 中只有显式使用 extern C { } 说明时,compiler 才把代码作为C处理


引用

int a = 3;
int & b = a;//创建a的引用

上面两行代码创建了变量 a 的引用 b,b 的类型为 int &
引用,即变量的别名,给一个变量起另外一个名字,即创建的引用与原变量表示同一块内存空间

void swap(int &a, int &b){
	int t = a;
	a = b; b = t;
}
int a = 5, b = 3;
swap(a, b);

函数 swap 使变量 a 与变量 b 的值进行了交换,因为 swap 的形参与实参表示同一块内存
或者说引用作为形参,可以接收到实参

常量引用
与指针类似
const int & b = a; const 住的是 &b,表示 b 引用的是一个常量,或者说 b 是一个常量
此时无法使用该引用修改该变量的值,且 const int & 不可隐式转换为 int &,反之可以
此外引用是不能修改的,b 一旦引用了 a,就不可以重新引用其它变量

引用初始化
引用创建时必须被初始化
常量引用才可以引用常量

引用作为返回值

int val;
int &returnVar(){
	return val;
}

甚至局部变量也可以作为返回值,但是由于局部变量保存在栈上,这份引用实际上是无效的

int &test(int &a, int &b) {
    int t = a;
    a = b;
    return b = t;
}

int main(){
    int a = 5;
    const int & b = 3;
    int &t = test(a, (int &)b);
    //test((int &)b, a);
    std::cout << t;
}

去或不去注释语句 t 分别输出为 5 和 3
但是这种用法还勉强可以当做

int  getLocalT(int t){
	return t;
} 

来使用

左值与右值
这里简单讨论一下左值右值,即 可作为赋值号左边的值 与 可作为可作为赋值号右边的值

变量由名字和存储空间构成
  名字用来表示这块存储空间,方便直接用名字进行读写,即左值
  存放在存储空间的变量的值,即右值
由上,左值还具有右值属性

引用即是使用变量的左值


动态内存分配

new
new T 相当于 malloc(sizeof(T)),返回一个指向堆中 sizeof(T) 大小的内存的指针
new T[num],返回一个大小为 num 类型为 T 的数组指针

delete
释放动态分配的内存

int *t = new int;
delete t;
int *t = new int[5];
delete []t;//释放这个数组 仅使用 delete t 将会造成内存泄漏

内联函数

C99也支持内联函数,然而C99的内联由编译器决定

在C++中,使用 inline 关键字,声明一个函数为内联函数,编译时在调用处展开
减小函数调用的开销从而提高效率,但是可能使可执行文件变大


重载

C++允许重载函数与运算符
函数重载与函数重写


函数参数缺省值

在C中,可以向指针类型的参数传递NULL,表示使用可选参数的默认值
C++函数在定义时可以使最右边连续多个参数有缺省值
同样使用时也必须是从最右边连续若干个参数缺省

void func(int num0, int num1 = 1, int num2 = 2){}
func(1);//即func(1,1,2);
func(1,2);//即func(1,2,2);
func(1,,4);//编译错误

要注意,使用函数缺省参数时要避免函数重载导致的二义性


C++的面向对象

基本特性:抽象 封装 继承 多态

C++的对象有三种使用方式

class Circle{
	public:
		double r;
		double getPerimeter(){ return 2*PI*r; }
		double getArea(){ return r*r*PI; }
		void init(int r_){ r = r_; }
};

//通过变量使用
Circle c;
c.init(5);
//通过引用使用
Circle &cr = c;
cout << c.getPerimeter();
//通过指针使用
Circle *cp = &c;
c->r = 6;
cout << c->getArea();

访问控制符:
  private (默认)
  protected
  public


命名空间

当类成员函数的声明与定义分开时,使用class::name指定使用的名字

class test{
	int a,b;
	public:
		void setA(int a_);
}

void test::setA(int a_){ a = a_; }//setA为类test中的setA

命名空间的定义

namespace A{
	int a = 1;
	namespace B{ //嵌套命名空间
		int a = 2;
	}
}

namespace A{ //向命名空间A中添加新的成员b
	int b;
}

int a = 3;

int main(){
	std::cout << a << std::endl;//3
    std::cout << A::a << std::endl;//1
    using std::endl;
    std::cout << A::B::a << endl;//2
    using namespace std;//使用命名空间,作用在后续代码
    int a = 4;
    cout << a << endl;//4
    cout << ::a << endl;//3
}

2020/1/14

posted @ 2020-01-14 17:08  kafm  阅读(157)  评论(0编辑  收藏  举报