C++的基本概念二

一、名字空间
    C语言中的名字空间的划分:全局、局部、块
    C++认为:全局空间用起非常方便,但如果把太多的东西放在全局空间会造成命名冲突,所以C++引用了这样一种机制就是名字空间。
    名字空间:把全局的命名空间进一步分割,可以创建出一个个独立的命名空间防止相互之间冲突。
    1、定义名字空间:
    namespace name
    {
        变量;
        函数;
        结构、类;
    }

    2、名字空间的合并
        a、同名的名字空间会自动合并。
        b、在同一个名字空间中只标识符必须是唯一的。
    
    3、定义与声明分开
    namespace n1
    {
        //在名字空间中声明函数
        void func(void);
    }

    // 在名字空间外定义函数
    void n1::func(void)
    {

    }

    4、如何使用名字空间中的内容
        a、域限定符(::),直接使用,名字空间::标识符,这样的好处是绝对不会冲突,但就是麻烦了些。
        b、using namespace 名字空间; 功能是把名字空间中的标识符对之后的代码全部公开。
        c、using 名字空间::标识符,表示此标识符对后面的代码公开。
    5、名字空间的嵌套
        名字空间可以嵌套,但使用时要逐层解析。
        namespace n1
        {
            int num = 10;
            namespace n2
            {
                int num = 20;
                namespace n3
                {
                    int num = 30;
                }
            }
        }
        n1::n2::n3::num == 30;
        n1::n2::num == 20;
        n1::num = 10;
        using namespace n1::n2;
    6、全局空间归属为匿名空间
        在全局空间定义的标识符都属于这个匿名空间,匿名空间默认开放。
        如果函数中有同名的标识符把匿名空间中的屏蔽了,可以使用空的域限定符表示它。

    注意:不同命名空间中的同名函数不构成重载,同一作用域下的同名函数叫重载。
    
二、class
    1、C++的class与struct一样,是一种复合数据类型。
    2、里面可以有变量用来表达属性,函数用来表示行为。
    3、在C++的class与struct,几乎没有任何区别。
    4、struct中默认访问属于是public,class中默认的访问属性是private。
    5、在C++默认使用class,以示与C语言中的struct进行区分。

三、class的构造函数
    1、在创建对象时自动调用的函数,在整个对象的生命周期中一定会被调用一次,且只能被调用一次。
    2、在构造函数中负责对成员变量的初始化、分配资源、设置对象的初始状态。
    3、构造函数可以有多个版本,这些不同的版本之间会构造重载,创建对象时的方式不同、给的参数不同会调用相应的构造函数,如果调用的构造函数不存在可能会造成编译错误。
        // 无参构造
        Student stu <=> Student* stup = new Student;
        Student stu(参数列表) <=> Student* stup = new Student(参数列表);
    4、如果类中没有定义构造函数,编译器会自动生成一个无参构造。
        一旦定义了其它版本的构造函数,无参构造就不会再生成了,因此为了防止无参方式创建对象出错,在定构造函数时,至少要实现两个。
    5、无参构造未必无参,在C++中函数可以有默认参数,如果有参构造全部设置了默认参数,就会和无参数构造有冲突,它们两个只能有一个存在。
    6、所谓的"编译器生成的某某函数"
        "编译器生成的某某函数",不是真正意义上的函数,编译作为指令的生成者,只要生成具有某些函数功能的指令即,没有必须生成高级语言的主义上的函数。
    7、什么时候调用无参构造
        a、Student stu <=> Student* stup = new Student;
        b、创建对象数组,每个对象都会调用一次无参构造。
        c、如果类A中有成员是类B,当执行守类A的构造函数前会自动调用类B的无参构造。
        d、在类A中如何调用类B的有参构造
        类A(参数列表):成员类B(参数列表)
        {
            ...
        }            
    8、类型转换构造函数
        用一个数据给对象初始化,默认会自动调用构造函数,达到类型转换的效果。
        这种方式虽然使用方便,但也会包容一些错误存在,如果想让代码检查更为严格可以使用explicit关键字禁止隐式转换的方式调用构造函数。
    9、也可以实现自动类型转换构造函数(默认)。

总结:

  • 名字空间:将自己声明的 变量名、函数名、结构名、类名归为一个名字空间,这样便于集中分类管理命名,减少命名冲突。名字空间可以嵌套,同名的名字空间自动合并,并且同一名字空间内标识符是唯一的。              注意:名字空间内可以初始化变量和结构体,但只能函数声明,不能函数定义(名字空间以外才行),使用::域限定符来确定名字空间内标识符的所属关系,其次,通过using namespace 名字空间名 来申请使用该名字空间。
  • namespace n1
    {
    	int num = 20;
    	void func(void);
    }
    namespace n2
    {
    	int num = 100;
    	void func(void);
    }
    void n1::func(void)
    {
    	cout << n2::num << endl;
    }
    
    void n2::func(void)
    {
    	cout << n1::num << endl;
    }
    int main()
    {
    	n1::func();
    	n2::func();
    }
  • 无参数构造函数:1、若未定义类的构造函数,就定义类,那么编译器会给类自动生成构造函数的相关指令。若定义了类的构造函数,编译器就不会自动生成构造函数(相关指令); 2、若需要定义类的具有默认参数的构造函数,一定不能与无参构造函数冲突,若一定会冲突就去掉无参构造函数 ;3、一般会为类定义一个无参函数和一个有参函数。
  • 类型转换构造函数:不是很懂,转换类型函数和类型转换构造函数。

练习:

定义一个Date类: year,month,day,在类里提供 
     1、年月日是否有效,返回bool类型
     2、是否是闰年,返回bool类型
     3、求nextday() ,返回下一天的日期
     4、写一个nextday(int n)表示n表后的日期,注意n可正可负(参考代码https://gitee.com/ZhongShengXueXi/codes/whx5qr4fane8scg3tj91k19

写一个Timer类(属性定义为私有,方法定义为公开)
     有一个属性 usigned int second;//second记录定时器的秒数
     有一个属性 Action action;//定时器响应动作
     typedef bool (*Action)(void *);
     有一个方法setAction(Action a),当调用begin()方法之后,second秒之后自动调用a函数。(参考代码https://gitee.com/ZhongShengXueXi/codes/pg5omuh9wtql1djef8xvy83

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值