zoukankan      html  css  js  c++  java
  • C++学习6

    类是一种数据类型,它类似于普通的数据类型,但是又有别于普通的数据类型。类这种数据类型是一个包含成员变量和成员函数的一个集合。

    类的成员变量和普通变量一样,也有数据类型和名称,占用固定长度的内存空间。但是,在定义类的时候不能对成员变量赋值,因为类只是一种数据类型,本身不占用内存空间,而变量的值则需要内存来存储。

    类的成员函数也和普通函数一样,都有返回值和参数列表,它与一般函数的区别是:成员函数是一个类的成员,出现在类体中,它的作用范围由类来决定;而普通函数是独立的,作用范围是全局的,或位于某个命名空间内。

    上节我们在最后的完整示例中给出了 Student 类的定义,如下所示:

     1 class Student{
     2 public:  //类包含的变量
     3     char *name;
     4     int age;
     5     float score;
     6 public:  //类包含的函数
     7     void say(){
     8         printf("%s的年龄是 %d,成绩是 %f
    ", name, age, score);
     9     }
    10 };

    上面的代码在类体中定义了成员函数。你也可以只在类体中声明函数,而将函数定义放在类体外面,如下图所示:

    class Student{
    public:
        char *name;
        int age;
        float score;
    public:
        void say();  //函数声明
    };
    //函数定义
    void Student::say(){
        printf("%s的年龄是 %d,成绩是 %f
    ", name, age, score);
    }

    在类体中直接定义函数时,不需要在函数名前面加上类名,因为函数属于哪一个类是不言而喻的。

    但当成员函数定义在类外时,就必须在函数名前面加上类名予以限定。::被称为域解析符(也称作用域运算符或作用域限定符),用来连接类名和函数名,指明当前函数属于哪个类。

    如果在域解析符“::”的前面没有类名,或者函数名前面既无类名又无域解析符“::”,如:

    //无类名
    ::say( ){
        //TODO
    }
    //无类名也无域解析符
    say( ){
        //TODO
    }

    则表示 say() 函数不属于任何类,这个函数不是成员函数,而是全局函数,即非成员函数的一般普通函数。

    成员函数必须先在类体中作原型声明,然后在类外定义,也就是说类体的位置应在函数定义之前,否则编译时会出错。

    inline 成员函数

    在类体中和类体外定义成员函数是有区别的:在类体中定义的成员函数为内联(inline)函数,在类体外定义的不是。

    内联函数一般不是我们所期望的,它会将函数调用处用函数体替代,所以我建议在类体内部对成员函数作声明,而在类体外部进行定义,这是一种良好的编程习惯。

    如果你既希望将函数定义在类体外部,又希望它是内联函数,那么可以在声明函数时加 inline 关键字,如下所示:

    在类体内部定义的函数也可以加 inline 关键字,但这是多余的,因为类体内部定义的函数默认就是内联函数。

    值得注意的是,如果在类体外定义 inline 函数,则必须将类定义和成员函数的定义都放在同一个头文件中(或者写在同一个源文件中),否则编译时无法进行嵌入(将函数代码的嵌入到函数调用出)。这样做虽然提高了程序的执行效率,但从软件工程质量的角度来看,这样做并不是好的办法,因此实际开发中较少在类中使用内联函数。

    C++类成员的访问权限

    C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。所谓访问权限,就是你能不能使用该类中的成员

    访问权限需要分两部分说明:类内和类外。

    • 在类内部,无论成员变量或成员函数被声明为 public、protected 还是 private,都是可以互相访问的,无访问权限限制。
    • 在类外部,通过对象无法访问 private、protected 属性的成员变量和成员函数,而仅可以访问 public 属性的成员变量和成员函数。
    #include <stdio.h>
    class Student{
    private:
        char *name;
        int age;
        float score;
    public:
        void setname(char *name1){
            name = name1;
        }
        void setage(int age1){
            age = age1;
        }
        void setscore(float score1){
            score = score1;
        }
        void say(){
            printf("%s的年龄是 %d,成绩是 %f
    ", name, age, score);
        }  
    };
    int main(){
        Student stu;
        stu.setname("小明");
        stu.setage(15);
        stu.setscore(92.5f);
        stu.say();
        return 0;
    }

    类中的成员变量 name、age 和 score 被设置成 private 属性,在类外部的代码都不能访问,即使通过该类创建的对象也不行。也就是说,私有成员变量和成员函数只能在类内部使用,在类外都是无效的。


    成员函数 setname()、setage() 和 setscore() 被设置为 public 属性,是公有的,可以通过对象访问。

    因为三个成员变量都是私有的,不能通过对象直接访问,所以必须借助三个 public 属性的成员函数来修改它们的值。

    private 成员的作用在于更好地隐藏类的内部实现,该向外暴露的接口都声明为 public,不希望外部知道、或者只在类内部使用的、或者对外部没有影响的成员,都建议声明为 private,这样的代码更加符合软件设计规范。

    另外还有一个关键字 protected,声明为 protected 属性的成员变量或成员函数,在类外也是不可以访问的,但是其派生类内部可以访问,我们将在后续章节介绍,在这里你只需要知道 protected 在类外无法访问即可。

    两点说明:
    1) 声明为 private 的成员和声明为 public 的成员的次序任意,既可以先出现 private 部分,也可以先出现 public 部分。如果既不写 private 也不写 public,就默认为 private。

    2) 在一个类体中,private 和 public 可以分别出现多次。每个部分的有效范围到出现另一个访问限定符或类体结束时(最后一个右花括号)为止。但是为了使程序清晰,应该养成这样的习惯,使每一种成员访问限定符在类定义体中只出现一次。

  • 相关阅读:
    让数据更精准,神器标配:热图
    运维监控大数据的提取与分析
    IT运营新世界大会:广通软件开启双态运维大时代
    持续交付的Mesos与Docker导入篇
    运算符
    Django 模型层(2)
    Django模型层
    Django的模板层
    Django的视图层
    Django的路由层(URLconf)
  • 原文地址:https://www.cnblogs.com/Caden-liu8888/p/5790986.html
Copyright © 2011-2022 走看看