zoukankan      html  css  js  c++  java
  • C++类


    类和对象初步
    面向对象的程序设计的基本特点:抽象,封装,继承,多态

    类的定义:
    class 类名{
        访问范围说明符:
         成员变量;
      ......
      成员函数;
      ......
    };
    访问范围一共有三种:public,private,protected

    成员变量、成员函数的写法与普通的变量、函数相同。

    一个类的成员函数之间可以相互调用。类的成员函数可以重载 ,也可以设定函
    数的默认值。

    成员函数的定义可以在类外:
    返回值类型 类名::函数名{
        函数体;

    所谓成员函数作用于某个对象上,指的是进入该成员函数时,函数中访问到的成
    员变量是属于该对象的。

    访问对象成员:
        对象名.成员名

        对象指针->成员名
     
    和结构变量一样,对象之间可以使用"="相互赋值,但不能进行比较运算

    #include <iostream>
    
    using namespace std;
    
    // 矩形类 
    class CRectangle{
        public:
            int w, h;
            void init(int w_, int h_);   // 设置宽度和高度 
            int area();                  // 求面积 
            int perimeter();             // 求周长 
    }; 
    
    void CRectangle::init(int w_, int h_){
        w = w_;
        h = h_; 
    }
    
    int CRectangle::area(){
        return w*h;
    }
    
    int CRectangle::perimeter(){
        return 2*(w + h);
    }
    
    int main()
    {
        int w, h;
        CRectangle r;
        cin >> w >> h;
        r.init(w, h);
        cout << "It's area is " << r.area() << endl;
        cout << "It's perimeter is " << r.perimeter() << endl;
        cout << sizeof(CRectangle) << endl;
        
        return 0;
    }

    类成员的访问范围:
        访问范围一共有三种:public,private,protected
        public: 指定公有成员,一个类的公有成员在任何地方都可以被访问
        private:用来指定私有成员,不论是成员变量还是成员函数,都只能在
     该类的成员函数内部才能被访问
         设置私有成员的机制叫做隐藏,隐藏的目的是强制对变量成员的访问
      要通过成员函数进行。这样做的好处是如果以后修改了成员变量的类
      型等属性,只需修改成员函数即可。否则需要修改所有访问成员变量
      的语句。
      隐藏机制可以避免对对象的不正确操作。
     protected:用来指定保护成员
     
     如果某个成员前面没有访问范围说明符,则对于class默认为私有成员
     

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    class CEmployee{
        private:
            char szName[30];
        public:
            int salary;
            void setName(char *name);
            void getName(char *name);
            void averageSalary(CEmployee e1, CEmployee e2);
    };
    
    void CEmployee::setName(char *name){
        strcpy(szName, name);
    }
    
    void CEmployee::getName(char *name){
        strcpy(name, szName);
    }
    
    void CEmployee::averageSalary(CEmployee e1, CEmployee e2){
        salary = (e1.salary + e2.salary) / 2;
    }
    
    int main()
    {
        CEmployee e;
        // strcpy(e.szName, "Tom");  error,不能访问私有成员 
        e.setName("Tom");
        e.salary = 50000;
        
        return 0;
    }

     构造函数:
        面向对象的程序设计语言倾向于对象一定要经过初始化后,使用起来才比较安全,因此才引入构造函数
     这一概念用于对对象进行自动初始化。
     构造函数是一类特殊的成员函数,其名字和类的名字一样,不写返回值类型,可以重载。
     如果类的设计者没有写构造函数,那么编译器会自动生成一个没有参数的构造函数。
     无参构造函数,不论是编译器自动生成的还是程序员写的,都称为默认构造函数。
     对象在生成时,一定会自动调用某个构造函数进行初始化,对象一旦生成,就再也不会在其上执行构造
     函数。

    #include <iostream>
    
    using namespace std;
    
    class Complex{
        private:
            double real, imag;
        public:
            // 构造函数
            Complex(double r);
            Complex(double r, double i);
            Complex(Complex c1, Complex c2);
    };
    
    Complex::Complex(double r){
        real = r;
        imag = 0;
        cout << "1" << endl; 
    }   
    
    Complex::Complex(double r, double i){
        real = r;
        imag = i;
        cout << "2" << endl;
    }
    
    Complex::Complex(Complex c1, Complex c2){
        real = c1.real + c2.real;
        imag = c1.imag + c2.imag;
        cout << "3" << endl;
    }
    
    int main()
    {
        Complex c1(3), c2(1, 2), c3(c1, c2), c4 = 7;
        
        return 0;
    }

     复制构造函数:
        复制构造函数时构造函数的一种,也称拷贝构造函数,它只有一个参数,参数类型是本类的引用。
     如果类的设计者不写复制构造函数,编译器会自动生成复制构造函数,它的作用是实现从源对象到目标对象
     逐个字节的复制。编译器自动生成的复制构造函数称为默认复制构造函数。默认构造函数不一定存在,但复
     制构造函数总会存在。
     复制构造函数的参数可以是const引用,也可以是非const引用。一般使用const引用,这样既可以使用常量作
     为参数,也可以使用非常量对象作为参数去初始化其它对象。
     
    复制构造函数被调用的三种情况:
        1)用一个对象去初始化同类的另一个对象
        2)作为形参的对象,用复制构造函数初始化的,而且调用复制构造函数时的参数,就是调用函数时所给的参数
        3)作为函数返回值的对象是用复制构造函数初始化的,而调用复制构造函数时的实参,就是return语句返回的
              对象

    #include <iostream>
    
    using namespace std;
    
    class Complex{
        public:
            double real, imag;
            Complex(double r, double i){
                real = r;
                imag = i;
            }
        // 无复制构造函数 
    };
    
    class Complex2{
        public:
            double real, imag;
            Complex2(double r, double i){
                real = r;
                imag = i;
            }
            Complex2(const Complex & c){    // 复制构造函数 
                real = c.real;
                imag = c.imag;
                cout << "Flag" << endl;
            } 
    };
    
    int main()
    {
        Complex c1(1, 2);   // 调用构造函数初始化 
        Complex c2(c1);     // 用默认复制构造函数初始化
        
        Complex2 c_1(1, 2);
        Complex2 c_2(c_1); 
        
        return 0;
    } 

     类型转换构造函数:
        只有一个参数的构造函数一般都可以称作类型转换构造函数,因为这样的构造函数能够起到类型
     自动转换的作用

    析构函数:
        成员函数的一种,它的名字与类名相同,但前面要加"~",没有参数和返回值。一个类有且仅有一个
     析构函数。如果定义类时没有写析构函数,则编译器生成默认析构函数。
     析构函数在对象消亡时自动被调用。可以定义析构函数在对象消亡后做善后工作。
     函数的参数对象以及作为函数返回值的对象,在消亡时也会引发析构函数调用。

    #include <iostream>
    
    using namespace std;
    
    class String{
        private:
            char *p;
        public:
            String(int n);    // 构造函数  
            ~String();        // 析构函数 
    }; 
    
    String::String(int n){
        p = new char[n];
    } 
    
    String::~String(){        //  利用析构函数释放所分配的动态内存 
        delete []p;
        cout << "Flag" << endl;    // 用于测试的标记 
    }
    
    int main()
    {
        String array[2] = {2, 2};
        String * pTest = new String(2);
        delete pTest;
        
        return 0;
    }

    构造函数、析构函数和变量的生存周期

    #include <iostream>
    
    using namespace std;
    
    class Demo{
        private:
            int id;
        public:
            Demo(int i){
                id = i;
                cout << "id = " << id << "constructed" << endl;
            } 
            
            ~Demo(){
                cout << "id = " << id << "destructed" << endl;
            }
    };
    
    Demo d1(1);
    
    void Func(){
        static Demo d2(2);
        Demo d3(3);
        cout << "func" << endl;
    }
    
    int main()
    {
        Demo d4(4);
        d4 = 6;
        cout << "main" << endl;
        Func();
        cout << "main ends" << endl;
        
        return 0;
    }
    
    /*
    输出结果:
        id = 1constructed
        id = 4constructed
        id = 6constructed
        id = 6destructed
        main
        id = 2constructed
        id = 3constructed
        func
        id = 3destructed
        main ends
        id = 6destructed
        id = 2destructed
        id = 1destructed 
    */ 
  • 相关阅读:
    安装 log.io 实时监控 php_error 日志
    macOS安装Solr并索引MySQL
    如何创建一个GitLab Web Hooks?
    在macOS Sierra 10.12搭建PHP开发环境
    在MySQL中,如何计算一组数据的中位数?
    mongodb 学习笔记
    percona教程:MySQL GROUP_CONCAT的使用
    MySQL GROUP_CONCAT函数使用示例:如何用一个SQL查询出一个班级各个学科第N名是谁?
    EF| CodeFirst 代码先行
    最经典25本Python编程开发电子书精粹
  • 原文地址:https://www.cnblogs.com/lnlin/p/7501538.html
Copyright © 2011-2022 走看看