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