C++ 随手笔记

1.引用

  作用: 给变量起别名。

#include <iostream>

int main()
{
    int a = 10;

    int &b = a;

    b = 20;
    cout << a << endl;  //a = 20      
}

  引用必须初始化,引用在初始化后不可改变(因为引用的本质是指针常量const )。

int &b; //错误,未初始化

int a = 10;
itn c = 20;
int &b = a;
b = c; //错误,初始化后不可改变,只是个赋值操作。

 

引用做函数参数:

  作用:函数传参时,可以利用引用让形参修饰实参。

#include <iostream>

void swap(int &a, int &b)
{
    int tmp;
    tme = a;
    a = b;
    b = tmp;
}

 

引用做函数返回值:

  注意:不要返回局部变量引用

  用法:函数调用作为左值

int& test()
{
    static int a = 10;
    return a;
}

int &p = test();

test() = 1000;
cout << p << endl; //p = 1000

 

常量引用:

  使用场景:用来修饰形参,防止误操作。

void test(const int &val)
{
    //val = 1000;   防止赋值操作
    cout << vla << endl;
}

int a = 10;
test(a);

  防止函数内部修改外部的变量值,理论上就是形参传值。但是当需要传递的值比如是一个大的数组,使用该方法更快以及省内存。

 

2.函数提供

函数默认参数:

int test(int a, int b = 20, int c = 30)
{
    return a +b +c;
}

cout << test(10) << endl; //60

  注意:如果某个位置已经有了默认参数,那么从这个位置往后,从左往右都要有默认参数

 int test(int a = 10, int b, int c = 30) //错误

  

  如果函数声明和函数实现只有一个有默认参数,不能同时都有默认参数(防止两个地方定义不一致,程序产生二义性)。

int test(int a = 10, int b = 20);

int test(int a, int b)
{
    return a+b;
}

或
int test(int a, int b)

int test(int a= 10, int b = 20)
{
    return a + b;
}

 

函数占位参数:

  作用:形参列表使用占位参数,用来占位,调用函数时必须填补该位置

void test(int a, int)

test(10, 10)
test(10) //错误

void test()int a, int = 10) //带默认参数是可行的

 

函数重载:

  作用:函数名相同,参数类型、个数、顺序不同,提高复用性.(函数返回值不能作为重载的条件)

void test()
{}
void test(int a)
{}
void test(double a)
{}
void test(int a, double b)
{}
void test(double a, int b)

test();
test(10);
test(10.00);
test(10, 10.00)
test(10.00, 10)

  注意事项:

  1.引用作为重载的条件

void test(int &a)
{}

void test(const int &a)
{}

以上是允许的,变量类型不同

int a = 10;
test(a); //引用第一个

test(10);//引用第二个

 

  2.函数重载中有默认参数

void fun(int a, int b = 10)
void fun(int a)

fun(10) //这个时候编译器会产生二义性
fun(10, 20)//会引用第一个

  所以函数重载尽量避免使用默认参数,避免存在二义性。

 

3.类和对象

   class和struct的区别,class默认权限是私有,struct默认是公用。

构造函数语法:

  类名(){}

1.构造函数,没有返回值也不写void

2.函数名称与类名相同

3.可以有参数,因此可以发生重载

4.创建对象的自动调用构造函数

 

析构函数语法:

  ~类名(){}

1.析构函数,没有返回值也不写void

2.函数名称与类名相同,在名称前加上符号~

3.析构函数不可以有参数,因此不可以重载

4.销毁对象自动调用析构函数

class Person{
    Person()
    {cout << "Person的构造函数" << endl;}
Person(
int a) { age = a; cout << "Person的有参构造函数" << endl; } Person(const Person &p) { age = p.age; cout << "Person的拷贝构造函数" << endl; } ~Person() {cout << "Person的析构函数" << endl;}
int age; }

调用:
Person p1; //无参
Person p2(10); //有参
Person p3(p2); //构造

 

int mian()
{
    Person p1();   //该行会被编译器认为是一个函数声明,不会去调用Person的构造函数
}

 

匿名对象:

Person p1;
Person p2 = Person(10);

  其中Person(10)是匿名对象,没有对象名称。特点:当前行执行结束后,系统会立即回收掉匿名对象。

  不要利用拷贝构造函数来初始化匿名对象。

  Person(p2), 编译器会等于是Person p2,相当于创建一个p2的对象。

 

拷贝构造函数调用时机“

  1.使用一个已经创建完毕的对象来初始化对象

Person p1(20);
Person p2(p1);

  2.值传递的方式给函数参数传值

void test(Person p)
{
    //这边Person p会调用拷贝构造函数,相当于实参p1拷贝了个副本给到p
}

Person p1;
test(p1)

 

  3.值方式返回局部对象

Person test()
{
    Person p1;  //局部变量会先调用构造函数
cout << "aaa" << endl; return p1; //因为p1是局部变量,所以先将p1复制一份返回,因此调用拷贝构造 } Person p = test(); //拷贝的p1赋值给p
cout << "bbb" < endl;

因此顺序:
p1构造 -> aaa -> p拷贝构造-> p1析构 -> bbb -> p析构

 

posted @ 2023-06-16 15:51  一个不知道干嘛的小萌新  阅读(3)  评论(0编辑  收藏  举报