当前位置 博文首页 > 张小懒君的博客:C++学习0

    张小懒君的博客:C++学习0

    作者:[db:作者] 时间:2021-09-20 13:41

    随意记录一下,不一定按照课程顺序和章节顺序来。以前接触过一些c,但是好久不用,有些忘记了,复习一些细节和重要的c++知识。为了能够更好学习Geant4。?

    每个视频都在讲C++是一个面向对象的语言,具有封装性,继承性和多态性。感觉这句话可能需要对C++有一定掌握了才能够比较好地理解。

    之前有听到过一个对C++是一个面向对象的语言的一个通俗的解释,比如:描述我们洗浴的过程,去浴室用水龙头洗,洗完擦拭干净就结束了。如果要用面向对象的语言描述:①对象:浴室门打开? ?②对象:水龙头打开? ③对象:人洗浴? ④对象:毛巾擦拭。这里边有四个对象,每个对象都有自己的属性和行为。如:门{ 木制,可旋转,接通和阻断空间;开/关?}? ?;毛巾{布的,吸水;使用吸水特性}等等,我们进入浴室时就要调用门的旋转特性打开它让人能够进入;洗浴完成后又需要调用毛巾的吸水特性来擦干。

    类和对象

    一、类的定义

    类:具有相同属性(数据)和行为(函数)的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包含属性和行为两个主要部分。利用类可以实现数据的封装、隐蔽、继承和派生。

    类简单来说,就是属性和方法的集合,属性就是类中的数据,方法就是调用这些属性数据进行操作的函数。

    class classname
    {
    
      //成员变量
      //成员函数
        public:                           //公有访问限定
                公有成员(外部接口)
        private:                          //私有访问限定
                私有成员
        protect:
                保护型成员
    
    };//要写分号

    类成员函数的两种定义方法:

    A:声明和定义都放在类体当中

    class classname
    {
        //在类体内定义和声明函数
        public:
            void SetClock(int h,int m,int s)
            {
            .........函数的具体定义..........
            }
    
    };

    B:声明和定义分开,类体内声明,类体外进行函数定义。(推荐)

    class classname(Clock)
    {
        //在类体内声明函数,在类外定义函数。
        public:
            void SetClock(int h,int m,int s)
    };
    
    //类外定义函数:在函数前,加类名、以及限定符::。
    void Clock::SetClock(int h,int m,int s)
    {
    .........函数的具体定义..........
    }

    二、类的访问限定符和封装

    1、访问限定符:public private protect

    公有成员在public后面声明,是类与外界的接口,任何外部函数都可以访问公有成员(数据和函数);私有成员在private后面声明,只允许本类中的函数访问,而类外部的任何函数都不能访问。保护类型的成员在protect后面声明,类外部的任何函数都不能访问,但是可以被继承。

    public:                          //公有成员在public后面声明,是类与外界的接口
    ????????成员数据
            成员函数
    
    private:                          //私有访问限定
            私有成员
    
    protect:
            保护型成员

    访问限定域:从访问限定符出现的位置到下一个访问限定符结束。

    class的默认访问权限为private? ,? struct默认为public

    2、封装

    面向对象的三个特性:封装、继承、多态

    封装本质上是一种管理手段,将属性(数据)和方法(接口)有机结合起来,再隐藏他们,之对外公开接口和对象进行交互。主要是因为class和访问修饰符的设计(public,private,protect)和只读(get)只写函数(set)。

    3、对象

    类的对象是该类对象的某一特定实体。

    声明形式: 类名 对象名:

    类中成员互相访问:直接使用成员名

    类外访问:“对象名.成员名”而且是public成员。

    三、class B:A? 类的继承

    class B : public A 是类的继承关系,即A类是B类的基类,类B继承于类A。

    当B继承A的时候,自动地将父类中所有的public成员继承了

    class Fruit
    {
    };
    
    class Apple : public Fruit
    {
    };
    
    //然后就可以在代码中使用子类定义对象了。
    Apple A;
    A.weight = 500*g
    A.taste = "sweet"
    
    //子类需要的成员中,父类有的内容就可以不用在定义了,没有的成员可以再定义。
    

    //子类需要的成员中,父类有的内容就可以不用在定义了,没有的成员可以再定义。public可以被继承,而private不能被继承,也不能被外部访问。public不能被访问,但可以被继承。

    class <派生类名>:<继承方式><基类名>
    {
    <派生类新定义成员>
    };

    虚拟继承和虚拟函数virtual

    子类可以继承父类的成员函数,但是,如果子类想改写父类中的某个成员函数的话,要怎么办呢?

    子类可以重写这个函数:

    class Parent
    {
    public:
        void Test();
    };
    
    class Child : public Parent
    {
    public:
        void Test();             //子类可以重写这个函数
    };
    
    int main()
    {
        Child ch;
        ch.Test();
    
        return 0;
    }

    如果要重写父类的成员函数时,我发现,父类的成员函数还有部分可用,要怎么办?

    class Parent
    {
    public:
        void Test();
    };
    
    class Child : public Parent
    {
    public:
        Parent::Test();          //先调用一下父类的函数即可
        void Test();             //子类可以重写这个函数
    };

    父类的指针指向子类的对象,是可以的:

    int main()
    {
        Child ch;
        
        Parent* p = &ch;    //父类的指针指向一个子类的对象
        p->Test();
    
        return 0;
    }

    思考一下,这个p->Test()会输出什么?

    结果是输出父类的Test()的结果,如果我想要输出子类的改写的成员函数的结果,要怎样做?

    当一个成员函数需要子类重写时,那么在父类中应该将其声明为virtual,作用是根据对象的实际类型,调用相应类型的函数。

    class Parent
    {
    public:
        virtual void Test();     //在父类的成员函数前加virtual;
    };
    
    class Child : public Parent
    {
    public:
        void Test();             //子类可以重写这个函数
    };
    

    C++的一些简单知识

    一、C++文件的编译运行:

    C++编辑软件一般会带有编译器,进到编译器的Bin目录,复制地址,添加到环境变量中。然后去到.cpp文件所在的目录,在路径输入框中输入cmd,会进入到该目录的命令窗口,然后输入:

    g++ 01.cpp? ?在该目录下会生成一个a.exe的文件。

    g++01.cpp? -o 01.exe? 那么在该目录下生成一个01.exe的文件。

    编译好后就可以运行了,在命令窗口输入:01.exe

    二、输入输出

    C++并未提供任何的输入输出语句,但是拥有一个全面的标准库来提供输入输出机制。比如:iostream库,其中包含两个基础的类型istream和ostream。

    cin? 读取数据

    cout? 输出数据? ? ; 输出还有cerr和clog,这两个一般会用在大型的程序中,用于输出错误。

    ?#?? ? ?预处理指令

    #include <iostream>
    int main()
    {
        std::cout << "Enter two numbers:" << std::endl;     //std::endl屏幕刷新和换行的意思。
        int v1 = 0, v2 = 0;
        std::cin >> v1 >> v2;
        std::cout << "The sum of " << v1 << " and " << v2 " is " << v1 + v2 << std::endl;
        return 0;
    }

    std是一个标准命名空间,cout是std下的一个操作符,需要用调用符(作用域运算符)::来调用cout ;命名空间可以帮助我们避免不经意的名称定义冲突,以及使用库中相同名字导致的冲突。

    注释

    //? ? 单行注释? ;? 快捷键 ctrl+/

    /*? ? ?多行注释,快捷键选中多行,ctrl+/

    *……

    */

    三、头文件和源文件

    一般后缀为?.h?的文件是头文件,内部包含函数声明、宏定义、结构体定义等内容。

    ? ? ? ?后缀为?.c?的文件是源文件,内部包含函数实现、变量定义等内容。

    头文件是源文件的辅助文件,include是一个预编译指令,后面一般不写分号,这个辅助文件可以是头文件也可以是其他任意格式的文件 .h? .c? .cpp??

    为防止头文件的重复包含,我们应该加上头文件的保护:

    #ifndef _OBJECT_H
    #define _OBJECT_H    //为防止多次包含头文件
    
    
    ........
    
    
    #endif

    #include "...h" 原理

    预编译指令,编译器在处理每个cpp文件之前,首先进行一个预处理,将所有的#include替换成该头文件的具体内容,然后在进行整体的编译。

    一个cpp文件要调用另一个cpp文件中的函数或者使用另一个cpp文件中的全局变量:

    extern: 声明外部函数或者声明外部全局变量。extern的作用,告诉编译器,在某个cpp文件中,存在这样一个函数/全局变量。

    extern double a                     //告诉编译器存在一个全局变量a
    extern double arr[5]                //告诉编译器存在一个全局数组arr ,外部声明不可以初始化
    
    extern double get_area(double r);
    extern int sum(int a, int b);

    cs