C++
一.定义
1.定义命名空间(namespace)-----可以用来定义名字完全相同的变量/函数
namespace N1{
int a;
void fun1(){
}
}
int a = 10;
//全局变量的定义和命名空间中的不影响,可以重定义
void fun1(){
printf("fun1()\n");
}
//分段定义,但N1中不能再出现N1前一段的,否则会重定义,报错
namespace N1{
int b;
void fun2(){
}
}
-------------------------------------访问命名空间下的成员(未通过using引入或者展开命名空间之前,需加作用域才能访问到成员)-----------------------------------------
①命名空间 + :: + 成员
printf("N1::a: %d\n", N1::a);
②using 命名空间 :: 成员
using N1::b;
printf("N1::b: %d\n",b);
③展开命名空间: using namespace 命名空间(不建议_相当于把命名空间中的变量展开,会和全局变量起冲突)
using namespace N1;
printf("N1::a: %d\n", a);
2.输入输出(C++头文件中定义的所有成员都属于std命名空间,可以在前面写using namespace std;)-----#include
①输入
int a;
std::cin>>a;
②.输出
int a;
std::cout<<a;
3.缺省参数(定义函数时,给参数一个默认值,它在函数不传值时使用)
void fun2(int a){
cout << a << endl;
}
void fun3(int a = 10){
cout << a << endl;
}
int main(){
fun2(100); //a取100使用
fun3(); //a取10使用
fun3(100); //a取100使用
}
①同函数名的重载__同一个作用域下,个数/类型不同(只有返回值类型不同,不能构成函数重载)__C++同名函数中,函数名/参数不同,在编译过程中可定义到不同函数:
void fun7(char a, int b){
cout << "fun7(char, int)" << endl;
}
void fun7(int b, char a){
cout << "fun7(int, char)" << endl;
}
void fun7(char a, int b, char c){
cout << "fun7(char, int, char)" << endl;
}
void test(){
int a = 1;
char b = 'a';
fun7(a, b); //fun7(int, char)
fun7(b, a); //fun7(char, int)
fun7(b, a, b); //fun7(char, int, char)
}
②运算符的重载(权限不能放大,但是可以缩小)
operator + 运算符
bool operator == (const Date& d){
return _year == d._year
&& _month == d._month
&& _day == d.day;
}
//将函数的默认this指针的类型改为const类型修饰
//本来()里是Date*类型的this指针,现在变为const Date* this
void Printf() const{
cout << _year << endl;
}
--------------设置默认值必须从右向左依次连续赋值,中间不能有间隔--------------
- 可:
void fun3(int a, int b = 10, int c = 20){
cout << a << b << c << endl;
}
- 不可:
void fun4(int a = 10, int b, int c = 20){
cout << a << b << c << endl;
}
void fun5(int a = 10, int b = 20, int c){
cout << a << b << c << endl;
}
--------------函数声明和定义只能有一个地方设置默认值,不能同时设置----------------
4.引用(不分配新的空间,和原数据共用空间,指向和原数据相同的实体)__*引用在定义时必须初始化
在引用时,相当于给它一个指针,只需要存放待求数据的指针,但在使用时,编译器自动解引用,不需要手动添加
int a = 10;
//ra是一个引用.是a的别名,指向和a相同的实体
int& ra = a;
struct A{
int a;
int b;
int c;
int d;
int e;
};
void test(){
A sa;
sa.a = 1;
sa.b = 1;
sa.c = 1;
sa.d = 1;
sa.e = 1;
//这里,改变rsa中的数据相当于改变sa中的数据
A& rsa = sa;
}
*//直接引用常数需要加const修饰
//直接引用常数需要加const修饰
const int& ra2 = 100;
*//临时变量具有常性,需要const接收
double d = 2.5;
int c = 10;
c = d;
const int& ra3 = d;
*①引用和指针的不同点:
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型
实体 - 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占
4个字节) - 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全
5.内联函数inline
//没有函数栈帧的开销
编译器在编译时,直接将inline修饰的函数展开为函数内部定义的指令
inline int add(int a, int b){
return a + b;
}
//inline函数在遇到循环或者迭代,相当于没有inline的函数
inline函数在使用后,地址不存在(当声明和定义不在同一个.cpp文件中时,会产生链接错误)
6.auto(C语言为作用周期,C++为自动变量类型)
auto定义时,必须要可以由别的推出来他的类型
auto a; //错误
auto a = 1; //正确
auto a = 10;
cout << typeid(a).name << endl; //int
auto声明指针类型时,auto和auto*没有区别
int a = 10;
int b = a;
auto pa = &a;
auto* pb = &b;
auto声明引用类型时,必须加&
int x = 10;
auto& c = x;
同一行定义多个变量时,代码中,auto定义的变量类型需要统一
auto a = 20, b = 10, c = 2.0; //报错
auto不能作为形参类型
void Test(auto a){ //错误
}
auto不能用来声明数组
auto b[] = {4, 5, 6}; //报错
7.范围for(当前的数据 : 循环的范围)
for (const int& e :arr){
cout << endl;
}
- 当范围for中使用数组名作为参数时,数组名退化为指针,数组范围不确定,不可用
for(arr[], arr){ //报错
}
8.struct VS class
struct默认访问方式是public,class默认访问方式是私有
9.构造函数
- const类型的变量必须在定义的时候初始化
①构造函数赋值(先定义,year取随机值,再赋值)
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
②初始化列表(在定义时直接赋值)
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year; //声明
int _month;
int _day;
};