c++函数重载、缺省参数、命名空间的解析

1.c和c++的优缺点解析

c语言属于面向过程。

优点是:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源。
缺点:没有面向对象易维护、易复用、易扩展

c++属于面向对象

优点是:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点:性能比面向过程低

面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性

而c++是基于面向对象的语言,因为它包含了c的一部分,而c语言是面向过程。面向对象更符合人类思维模式。

2.函数重载解析

各位应该都知道在c语言中不支持重载,而c++中却支持重载,这是为什么呢?接下来我们仔细分析分析。

举例创建三个文件:test.h test.c main.c
执行文件时分为下面四个过程

过程执行的操作生成的文件
1.预处理展开头文件、宏替换、去掉注释、条件编译test.i main.i
2.编译检查语法词法并生成汇编代码test.s main.s
3.汇编汇编代码变为机器认识的机器码test.0 main.o
4.链接链接到一起生成可执行程序a.out
这是main.c中的函数
#include"test.h"

void func(int i)
{
    count<<i<<endl;
}

int main()
{
    func(10);
    func("c");

}
这是test.c的函数
#include"test.h"

void func(char c)
{
    count<<"hello world"<<endl;
}
这是test.h函数
#pragma once
#include<stdio.h>
#include<windows.h>

当你这时候编译时就会出现这种错误: fatal error LNK1169: 找到一个或多个多重定义的符号

这就是重定义的错误,就算两个函数参数不一样,但依然还会重定义,因为在c语言链接时将main.o和test.o 合并时,在两个文件中查找func函数,当发现两个文件中都有func函数就会产生冲突,因为它是以名字查找的。
而c++是可以重载的
eg:

原函数Linux下的反汇编定义的函数名字
void func(int i)_Z4funci
void func(char c)_Z4funcc
int max(int a,int b)_Z3maxii
double max(double a,double b)_Z3maxdd

看上面例子可得:c++ 中底层汇编语言中会将重载函数名映射为返回类型+函数名+参数列表。这样c++有同名函数时,链接时只要参数类型或者顺序不一样就可以调用

3.缺省参数解析

c++中的缺省参数定义:在声明函数的某个参数的时候为之指定一个默认值,在调用该 函数的时候如果使用默认值,你就没必要指定该参数了。

void func2(int x, int y = 40);//声明
void func1(int x = 10, int y = 20)//定义
{
    cout << x << ' ' << y << endl;

}
void func2(int x, int y)
{

    cout << x << ' ' << y << endl;

}
void func3(int x = 10, int y = 20)
{
    cout << x << ' ' << y << endl;

}
int main()
{

    func1();
    func2(30);
    func3(50,60);
    system("pause");
    return 0;
}

就像func1在调用时实参为空,这就叫做缺省参数,而在定义时有默认参数并且已经给出默认值,函数调用时就可以直接调用。而func2中只省略了右边参数y的值,因此实参只写了一个参数,func3中实参都写了,所以调用时就不会用到默认参数的值,如果没有写就会直接调用默认参数

缺省参数有一下规则:

1.调用时你只能从最后一个参数开始进行省略,中间不能间断。

void func(int a=1,int b,int c=3, int d=4); //error 

2.缺省值必须是常量
3.函数声明时有默认参数,定义时就不能给出默认参数了,就像func2()一样
4.默认参数与函数重载一块使用时就要注意了

如果一组重载函数(可能带有默认参数)都允许相同实參个数的调用,将会引起调用的二义性。例如:

void func(int x); //重载函数一
void func(int x,int y=4); //重载函数二,带有默认参数
void func(int x=3int y=4); //重载函数三,带有默认参数
func(7); //error: 到底调用3个重载函数中的哪个?
func(20,30) //error:到底调用后面2个重载函数的哪个?

这样就会出现问题,所以读者在应用时要特别注意

5.默认值的限定:默认值可以是全局变量、全局常量,甚至是一个函数,但不能是局部变量,局部变量

因为默认参数的函数调用是在编译时确定的,而局部变量的位置与值在编译时均无法确定

4.命名空间解析

命名空间:在C++ 中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。为了避免在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间),这些标识符的作用域只在本空间域内有效,从而合理的解决命名冲突。
eg:

 namespace n1
{
    int a = 30;
    namespace n2
    {
        int a = 20;
    }
}

cout << n1::a << endl;
cout << n1::n2::a << endl;

上面例子说明在不同的命名空间里可以定义相同的名称,不会出现命名冲突问题

c++中有一个标准的命名空间
using namespace std;

C++ 库的所有标识符都是在std的命名空间中定义的,或者说标准头文件(iostream)中的函数、类、对象和类模板是在命名空间std中定义的。所以在C++程序的一开始,就用using namespace对std进行全局声明

如果你一开始不写这个命名空间就会编译出错,要么你就得给所以std命名空间下的成员加上这个eg:

    std::cout << n1::a << std::endl;
    std::cout << n1::n2::a << std::endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值