c++入门:重载与引用

函数重载

  在这个问题前需弄明白,为什么c语言不支持函数重载,而祖师爷在c++创作出来却支持,c与c++的思考方式到底有那些区别

#include<iostream>
using namespace std;

void func(int i, double d)
{
	cout << "void func(int i, double d)" << endl;
}

void func(double d, int i)
{
	cout << "void func(int i, double d)" << endl;
}

int main()
{
	func(1, 1.1);
	func(1.1, 1);
}

  从本质开始,代码运行后会经历一下四个阶段:

test.cpp :预处理  头文件展开/宏替换/去掉注释/条件编译

test.i :编译  检查语法, 生成汇编代码(指令级代码)

test.s :汇编  将汇编代码生成二进制机械码

test.o :链接  合并链接, 生成可执行程序

  于是c++在编译时与c产生差别,使其能分辨同名韩式使函数重载,这个规则是函数名修饰规则

c++修饰规则:

   在编译中讲int类型记作H,double类型记作N,以不同的标记使函数重载,来分开同名函数。

c语言修饰规则:

 仅仅只是用函数名字来区分,并不会深入分析,这就造成c语言无法开辟同名函数。

但是返回值有无情况下无法构成函数重载:

 除非使用红字方式,但是这样颇为麻烦。最后附上一张转换表。

 引用:

 引用使本贾尼祖师爷为了修改指针的不足而设立。

void TestRef()
{
	int a = 10;
	int& ra = a;

	printf("%p\n", &a);
	printf("%p\n", &ra);
}

 引用特性:

1,引用在定义时必须初始化。

2,一个变量可以多个引用。

3,引用一旦引用一个实体,在不能引用其他实体。

 

void TestRef()
{
	int b = 0;
	int a = 10;
	int& ra = a;
	int& ra = b;//无法再次引用

	printf("%p\n", &a);
	printf("%p\n", &ra);
}

  引用对我们的好处:

1,

void swap(int& x1, int& x2)
{
    int tmp = x1;
    x1 = x2;
    x2 = tmp;
}

int main()
{
    int size;
    preorderTraversal(nullptr, size);

    int x = 0, y = 1;
    swap(x, y);/这里能够直接交换。

    return 0;
}

2,c的玩法:

 //c语言二级指针的玩法
void PushBack(ListNode** pphead, int x)
{
    ListNode* newnode;
    if (*pphead == NULL)
    {
        *pphead = newnode;
    }
    else
    {
    }
}

int main()
{
    ListNode* plist = NULL;
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);

    return 0;
}

c++玩法:

// CPP,引用的玩法
void PushBack(ListNode*& phead, int x)
//void PushBack(PListNode& phead, int x)//取ListNode地址
{
    ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
    // ...
    if (phead == NULL)
    {
        phead = newnode;
    }
    else
    {

    }
}

int main()
{
    ListNode* plist = NULL;
    PushBack(plist, 1);
    PushBack(plist, 2);
    PushBack(plist, 3);

    return 0;
}

关于有返回值函数的调用:

int Count1()
{
	int n = 0;
	n++;
	
	// ...
	return n;
}
int& Count2()
{
	int n = 0;
	n++;
	
	// ...
	return n;
}

int main()
{
	int ret = Count1();//值会正常传,但是可能是1,可能是随机值,但是值未被清,正常传
    int ret = Count2();// 这里打印的结果可能是1,也可能是随机值,是值被清,无法传
	
	cout << ret << endl;
	cout << ret << endl;

	return 0;
}

传值和引用作为函数参数传参的速度比较:

#include <time.h>
struct A { int a[10000]; };

A a;
// 值返回
A TestFunc1() { return a; }

// 引用返回
A& TestFunc2() { return a; }

void TestReturnByRefOrValue()
{
	// 以值作为函数的返回值类型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();

	// 以引用作为函数的返回值类型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();

	// 计算两个函数运算完成之后的时间
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

// 传引用传参(任何时候都可以用)
// 1、提高效率
// 2、输出型参数(形参的修改,影响的实参)

// 传引用返回(出了函数作用域对象还在才可以用)!!!
// 1、提高效率
// 2、修改返回对象

  c++比c修改值方便的最后一处:
 

 C的接口设计
 读取第i个位置的值
int SLAT(struct SeqList* ps, int i)
{
	assert(i < ps->size);
	// ...
	return ps->a[i];
}
 修改第i个位置的值
void SLModify(struct SeqList* ps, int i, int x)
{
	assert(i < ps->size);

	// ...
	ps->a[i] = x;
}

 CPP接口设计

 读 or 修改第i个位置的值

int& SLAT(struct SeqList& ps, int i)
{
	assert(i < ps.size);
	// ...
	return (ps.a[i]);
}

int main()
{
	struct SeqList s;
	s.size = 3;
	// ...
	SLAT(s, 0) = 10;
	SLAT(s, 1) = 20;
	SLAT(s, 2) = 30;
	cout << SLAT(s, 0) << endl;
	cout << SLAT(s, 1) << endl;
	cout << SLAT(s, 2) << endl;

	return 0;
}

最后,引用只能缩小或者平等原来的权力,不能超过:

int func()
{
	int a = 0;

	return a;
}

int main()
{
	const int& ret = func();

	const int a = 0;

	// 权限的放大
	// int& b = a;
	
	//int b = a; 可以的,因为这里是赋值拷贝,b修改不影响a

	// 权限的平移
	const int& c = a;

	// 权限的缩小
	int x = 0;
	const int& y = x;

	int i = 0;
	const double& d = i;

	return 0;
}

新手还有诸多不足,多多包涵!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值