写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。
标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。
点击此处进入学习日记的总目录
2024.02.01
- 一、C++:&——引用变量
- 二、C++:默认实参
- 三、C++:::——一元作用域运算符
- 四、C++:函数重载
一、C++:&——引用变量
引用变量是一个巨有用,巨简洁的传递变量用法,类似于指针,但更简洁。
引用变量是用 & 符号来声明的。如果学过C语言的同学,可能知道 & 可以获取变量的地址,但是C++给 & 符号赋予了另一个函数——声明引用变量。例如,要将 b 作为 a 变量的别名,可以这么做:
int a;
int &b = a; // b 是 a 变量的别名
其中,&不是地址运算符,而是类型标识符的一部分。就类似声明 char* 指的是指向 char 的指针一样, int &指的是指向 int 的引用。
上述引用声明完后,a和b就指向相同的值和内存单元(即b是a变量的别名)。
#include <iostream>
using namespace std;
int main()
{
int a = 5;
int& b = a;
cout << "a = " << a << ", a address: " << &a << endl;
cout << "b = " << b << ", a address: " << &b << endl;
return 0;
}
可以看到,变量a b的地址都是一样的,换句话说,就是a就是b
大家可以在下面实验:
- 如果我们用指针写一个交换两个数的函数,代码如下:
#include<stdio.h>
void Swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
int a = 5;
int b = 3;
Swap(&a, &b);
printf("a = %d\nb = %d",a,b);
return 0;
}
结果为:
本函数需要在Swap函数中频繁的使用 *,并且Swap函数中a和b本质上是形参。
- 那么如果用 引用变量 来写呢:
#include<stdio.h>
void Swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main() {
int a = 5;
int b = 3;
Swap(a, b);
printf("a = %d\nb = %d",a,b);
return 0;
}
结果如下:
可以看到,程序简洁了很多
- 何时使用引用参数
一、传递值而不修改值(尽量 const 修饰)
1、内置数据类型:由于较小,可直接按值传递;
2、数组:采用 const 修饰的指针;
3、较大的结构:使用 const 指针或 const 引用,可提高效率、节省时间空间;
4、类对象:const 引用。
二、需要修改原数据
1、内置数据类型:可使用指针;
2、数组:只能使用指针;
3、较大的结构:使用指针或引用;
4、类对象:const 引用。
- 引用这么高效为什么内置类型不使用引用呢?
《Effective C++》条款20:宁以pass by reference to const替换pass by value。
其中有这么一句“如果你有个对象属于内置类型(例如int) pass by value 往往比 pass by reference 的效率高些”。
说白了就是自己的东西用的更顺手一些。
参考资料:
C+±–引用变量(&)
C++——引用变量
C++ | 引用变量
二、C++:默认实参
某些函数有这样一种形参, 在函数的很多次调用中它们都被赋予一个相同的值, 我们把这个反复出现的值称为函数的默认实参。
调用含有默认实参的函数时, 可以包含该实参, 也可以省略该实参。
对于有多个形参的函数, 必须从右向左添加默认值。
三、C++:::——一元作用域运算符
在C ++中,作用域运算符为::
它用于以下目的。
- 当存在具有相同名称的局部变量时,要访问全局变量:
// C++ program to show that we can access a global variable
// using scope resolution operator :: when there is a local
// variable with same name
#include<iostream>
using namespace std;
int x; // Global x
int main()
{
int x = 10; // Local x
cout << "Value of global x is " << ::x;
cout << "\nValue of local x is " << x;
return 0;
}
输出:
全局x的值为0
本地x的值为10
- 在类之外定义函数。
// C++ program to show that scope resolution operator :: is used
// to define a function outside a class
#include<iostream>
using namespace std;
class A
{
public:
// Only declaration
void fun();
};
// Definition outside class using ::
void A::fun()
{
cout << "fun() called";
}
int main()
{
A a;
a.fun();
return 0;
}
输出:
fun() called
- 访问一个类的静态变量。
// C++ program to show that :: can be used to access static
// members when there is a local variable with same name
#include<iostream>
using namespace std;
class Test
{
static int x;
public:
static int y;
// Local parameter 'a' hides class member
// 'a', but we can access it using ::
void func(int x)
{
// We can access class's static variable
// even if there is a local variable
cout << "Value of static x is " << Test::x;
cout << "\nValue of local x is " << x;
}
};
// In C++, static members must be explicitly defined
// like this
int Test::x = 1;
int Test::y = 2;
int main()
{
Test obj;
int x = 3 ;
obj.func(x);
cout << "\nTest::y = " << Test::y;
return 0;
}
输出:
静态x的值为1
本地x的值为3
测试:: y = 2
- 如果有多个继承:
如果两个祖先类中存在相同的变量名,则可以使用作用域运算符进行区分。
// Use of scope resolution operator in multiple inheritance.
#include<iostream>
using namespace std;
class A
{
protected:
int x;
public:
A() { x = 10; }
};
class B
{
protected:
int x;
public:
B() { x = 20; }
};
class C: public A, public B
{
public:
void fun()
{
cout << "A's x is " << A::x;
cout << "\nB's x is " << B::x;
}
};
int main()
{
C c;
c.fun();
return 0;
}
输出:
A的x是10
B的x是20
- 对于命名空间
如果两个命名空间中都存在一个具有相同名称的类,则可以将名称空间名称与作用域解析运算符一起使用,以引用该类而不会发生任何冲突
// Use of scope resolution operator for namespace.
#include<iostream>
int main(){
std::cout << "Hello" << std::endl;
}
在这里,cout和endl属于std命名空间。
- 在另一个类中引用一个类:
如果另一个类中存在一个类,我们可以使用嵌套类使用作用域运算符来引用嵌套的类
// Use of scope resolution class inside another class.
#include<iostream>
using namespace std;
class outside
{
public:
int x;
class inside
{
public:
int x;
static int y;
int foo();
};
};
int outside::inside::y = 5;
int main(){
outside A;
outside::inside B;
}
四、C++:函数重载