zoukankan      html  css  js  c++  java
  • 第十二章 类

    code:

    /*
    
    
    第三部分 类和数据抽象
    
    
    第12章 类
    12.1 类的定义和声明
    12.2 隐含的this指针
    12.3 类作用域
    12.4 构造函数
    12.5 友元
    12.6 static类成员
    小结
    
    
    
    
    第三部分 类和数据抽象
    第12章 类 367
    12.1 类的定义和声明 368
    12.1.1 类定义:扼要重述 368
    12.1.2 数据抽象和封装 369
    12.1.3 关于类定义的更多内容 372
    12.1.4 类声明与类定义 374
    12.1.5 类对象 375
    12.2 隐含的this指针 376
    12.3 类作用域 380
    类作用域中的名字查找 382
    12.4 构造函数 385
    12.4.1 构造函数初始化式 387
    12.4.2 默认实参与构造函数 391
    12.4.3 默认构造函数 392
    12.4.4 隐式类类型转换 393
    12.4.5 类成员的显式初始化 396
    12.5 友元 396
    12.6 static类成员 398
    12.6.1 static成员函数 400
    12.6.2 static数据成员 400
    小结 403
    术语 403
    
    
    */
    
    
    
    // 12.1 类的定义和声明 -------------------------------------------------------------------------------------------------
    
    // in book
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <list>
    #include <algorithm>
    #include <iterator>
    using namespace std;
    
    class Sales_item
    {
      public:
        // operations on Sales_item objects
        double avg_price()const;
        bool same_isbn(const Sales_item &rhs)const
        {
            return isbn == rhs.isbn;
        }
        // default constructor needed to initialize members of built-in type
        Sales_item(): units_sold(0), revenue(0.0){} // 构造函数初始化列表
      private:
        std::string isbn;
        unsigned units_sold;
        double revenue;
    };
    
    double Sales_item::avg_price()const
    {
      if(units_sold)
        return revenue / units_sold;
      else
        return 0;
    }
    
    int main()
    {
      return 0;
    }
    
    
    // test this
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <list>
    #include <algorithm>
    #include <iterator>
    using namespace std;
    
    class Sales_item
    {
      public:
        // operations on Sales_item objects
        double avg_price() const;
        bool same_isbn(const Sales_item &rhs) const
        {
            return this->isbn == rhs.isbn; //
        }
        // default constructor needed to initialize members of built-in type
        Sales_item(): units_sold(0), revenue(0.0){} // 构造函数初始化列表
      private:
        std::string isbn;
        unsigned units_sold;
        double revenue;
    };
    
    double Sales_item::avg_price() const // const 成员函数不能改变其所操作的对象的数据成员
    {
      if(this->units_sold)
        return this->threvenue / this->units_sold; //
      else
        return 0;
    }
    
    int main()
    {
      return 0;
    }
    
    
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Screen
    {
      public:
        // interface member functions
      private:
        std::string contents;
        std::string::size_type cursor;
        std::string::size_type height, width;
    };
    
    int main()
    {
      return 0;
    }
    
    
    // typedef
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Screen
    {
      public:
        // interface member functions
      private:
        std::string contents;
        std::string::size_type cursor;
        std::string::size_type height, width;
    };
    
    class Screen2
    {
      public:
        // interface member functions
        typedef std::string::size_type index;
      private:
        std::string contents;
        index cursor;
        index height, width;
    };
    
    int main()
    {
      return 0;
    }
    
    
    // 函数重载
    #include <iostream>
    #include <string>
    using namespace std;
    class Screen
    {
      public:
        typedef std::string::size_type index;
        // return character at the cursor or at a given position
        char get()const
        {
            return contents[cursor];
        } 
        char get(index ht, index wd)const;
        // remaining members
      private:
        std::string contents;
        index cursor;
        index height, width;
    };
    
    char Screen::get(index h, index w) const
    {
      return( 't' ); // just for test
    }
    
    int main()
    {
      Screen myscreen;
      char ch = myscreen.get(); // calls Screen::get()
      ch = myscreen.get(0, 0); // calls Screen::get(index, index)
      return 0;
    }
    
    
    
    // inline
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Screen
    {
      public:
        typedef std::string::size_type index;
        // implicitly inline when defined inside the class declaration
        char get()const
        {
            return contents[cursor];
        }
        // explicitly declared as inline; will be defined outside the class declaration
        inline char get(index ht, index wd)const;
        // inline not specified in class declaration, but can be defined inline later
        index get_cursor()const;
      private:
        std::string contents;
        index cursor;
        index height, width;
    };
    
    // inline declared in the class declaration; no need to repeat on the definition
    char Screen::get(index r, index c)const
    {
      index row = r * width; // compute the row location
      return contents[row + c]; // offset by c to fetch specified character
    }
    
    // not declared as inline in the class declaration, but ok to make inline in definition
    inline Screen::index Screen::get_cursor()const  // 定义类型的成员,如 Screen::index,使用作用域操作符来访问。
    {
      return cursor;
    }
    
    int main()
    {
      class Screen myscreen; // class 经常不写
      char ch = myscreen.get(); // calls Screen::get()
      ch = myscreen.get(0, 0); // calls Screen::get(index, index)
      return 0;
    }
    
    
    // 12.2 隐含的this指针 -------------------------------------------------------------------------------------------------
    
    // this
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Screen
    {
      public:
        typedef std::string::size_type index;
        // interface member functions
        Screen &move(index r, index c);
        Screen &set(char);
        Screen &set(index, index, char);
        // other members as before
      private:
        std::string contents;
        index cursor;
        index height, width;
    };
    
    Screen &Screen::set(char c)
    {
      contents[cursor] = c;
      return  *this;
    }
    
    Screen &Screen::move(index r, index c)
    {
      index row = r * width; // row location
      cursor = row + c;
      return  *this;
    }
    
    int main()
    {
      class Screen myScreen;
      myScreen.move(4,0).set('#');
    
      return 0;
    }
    
    
    
    // 基于 const 的重载
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Screen
    {
      public:
        typedef std::string::size_type index;
        // interface member functions
        Screen &move(index r, index c);
        Screen &set(char);
        Screen &set(index, index, char);
        //Screen(): height(0), width(0){} // 构造函数初始化列表 //
        //Screen( index i, index j ) { height=i; width=j; }  // 加这两句
        Screen(index i,index j):height(i),width(j){} // 也可以这样构造初始化列表
        // display overloaded on whether the object is const or not
        Screen& display(std::ostream &os)
          { do_display(os); return *this; }
        const Screen& display(std::ostream &os) const
          { do_display(os); return *this; }
      private:
        void do_display(std::ostream &os) const
          { os << contents; }
        std::string contents;
        index cursor;
        index height, width;
    };
    
    Screen &Screen::set(char c)
    {
      contents[cursor] = c;
      return  *this;
    }
    
    Screen &Screen::move(index r, index c)
    {
      index row = r * width; // row location
      cursor = row + c;
      return  *this;
    }
    
    int main()
    {
      Screen myScreen(5,3);
      const Screen blank(5, 3);
      myScreen.set('#').display(cout); // calls nonconst version
      blank.display(cout);             // calls const version
    
      return 0;
    }
    
    
    // 可变数据成员
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Screen
    {
      public:
        typedef std::string::size_type index;
        Screen &move(index r, index c);
        Screen &set(char);
        Screen &set(index, index, char);
        Screen(index i,index j):height(i),width(j){}
        Screen& display(std::ostream &os)
          { do_display(os); return *this; }
        const Screen& display(std::ostream &os) const
          { do_display(os); return *this; }
      private:
        void do_display(std::ostream &os) const
        { 
          ++access_ctr; // keep count of calls to any member function
          os << contents; 
        }
        mutable size_t access_ctr; // 可变数据成员 may change in a const members    
        std::string contents;
        index cursor;
        index height, width;
    };
    
    Screen &Screen::set(char c)
    {
      contents[cursor] = c;
      return  *this;
    }
    
    Screen &Screen::move(index r, index c)
    {
      index row = r * width; // row location
      cursor = row + c;
      return  *this;
    }
    
    int main()
    {
      Screen myScreen(5,3);
      const Screen blank(5, 3);
      myScreen.set('#').display(cout); // calls nonconst version
      blank.display(cout);             // calls const version
    
      return 0;
    }
    
    
    
    // 12.3 类作用域 -------------------------------------------------------------------------------------------------
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class First
    {
      public:
        int memi;
        double memd;
    };
    
    class Second
    {
      public:
        int memi;
        double memd;
    };
    
    int main()
    {
      First obj1;
      // Second obj2 = obj1; // error: obj1 and obj2 have different types
      return 0;
    }
    
    
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class First
    {
      public:
        int memi;
        double memd;
        void tempf(){ cout << "test" << endl; }
    };
    
    int main()
    {
      First obj;
      First *ptr = &obj;
      ptr->memi;
      obj.memi;
      ptr->tempf();
      obj.tempf();
      
      return 0;
    }
    
    
    
    // 类作用域中的名字查找
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    int i(43);
    
    class First
    {
      public:
        int memi;
        double memd;
        void tempf(){ cout << i << endl; } // 贯穿。全局变量一样贯穿进去
    };
    
    
    int main()
    {
      First obj;
      First *ptr = &obj;
      ptr->tempf();
      obj.tempf();
      
      return 0;
    }
    
    
    
    
    // 12.4 构造函数 -------------------------------------------------------------------------------------------------
    
    
    // 实参决定使用哪个构造函数
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Sales_item
    {
        // other members as before
      public:
        // added constructors to initialize from a string or an istream
        Sales_item(const std::string &){cout << "string" << endl; };
        Sales_item(std::istream &){cout << "istream" << endl; };
        Sales_item(){ cout << "nothing" << endl; }; // just for test
    };
    
    int main()
    {
      // uses the default constructor:
      // isbn is the empty string; units_soldand revenue are 0
      Sales_item empty;
      // specifies an explicit isbn; units_soldand revenue are 0
      Sales_item Primer_3rd_Ed("0-201-82470-1");
      // reads values from the standard input into isbn, units_sold, and revenue
      Sales_item Primer_4th_ed(cin);
      
      return 0;
    }
    
    
    // 并非所有类成员都会默认初始化——内置类型的成员不进行隐式初始化
    // **没有默认构造函数的类类型的成员,以及 const 或引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。**
    #include <iostream>
    #include <string>
    using namespace std;
    
    class First
    {
      public:
        int i;
        double d;
        string s; // 已经初始化为 empty tring
    };
    
    int main()
    {
      First obj;
      First *ptr = &obj;
      cout << ptr->i << endl; // 基本数据类型没有初始化
      cout << ptr->s << endl;
      cout << ptr->d << endl;
      
      return 0;
    }
    
    
    
    
    //下面的构造函数是错误的:
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class ConstRef
    {
      public:
        ConstRef(int ii);
      private:
        int i;
        const int ci;
        int &ri;
    };
    
    // no explicit constructor initializer: error ri is uninitialized
    ConstRef::ConstRef(int ii)
    {
      // assignments:
      i = ii; // ok
      ci = ii; // error: cannot assign to a const
      ri = i; // assigns to ri which was not bound to an object
    }
    
    int main()
    {
      ConstRef refobj(42);
    
      return 0;
    }
    
    
    /*
    记住,可以初始化 const 对象或引用类型的对象,但不能对它们赋值。在开始执行构造函数的函数体之前,要完成初始化。
    初始化 const 或引用类型数据成员的唯一机会是构造函数初始化列表中。
    必须对任何 const 或引用类型成员以及没有默认构造函数的类类型的任何成员使用初始化式。
    */
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class ConstRef
    {
      public:
        // ok: explicitly initialize reference and const members
         ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }
      private:
        int i;
        const int ci;
        int &ri;
    };
    
    int main()
    {
      ConstRef refobj(42);
    
      return 0;
    }
    
    
    
    /*
    构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。
    成员被初始化的次序就是定义成员的次序。
    所有会有警告:warning: 'X::j' will be initialized after
    
    按照与成员声明一致的次序编写构造函数初始化列表是个好主意。此外,尽可能避免使用成员来初始化其他成员。
    
    */
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    class X
    {
        int i;
        int j;
      public:
        // run-time error: i is initialized before j
        X(int val): j(val), i(j){} // 实际上是按定义的顺序。。即先i,再j
    };
    
    int main()
    {
      X refobj(42);
      return 0;
    }
    
    
    
    // 12.5 友元 -------------------------------------------------------------------------------------------------
    
    // 12.6 static类成员 -------------------------------------------------------------------------------------------------
    
    
    // 书中只提供代码片断,要补全,比较坑爹。。总算编译成功。。
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Account
    {
      public:
        // interface functions here
        void applyint(){ amount += amount * interestRate; }
        static double rate() { return interestRate; }
        static void rate(double); // sets a new rate
      private:
        string owner;
        double amount;
        static double interestRate;
        static double initRate();
    };
    
    void Account::rate(double newRate)
    {
      interestRate = newRate; // sets a new rate
    }
    
    double Account::initRate() // for interestRate
    {
      return(3.14/100);
    }
    
    double Account::interestRate = initRate(); // only once
    
    int main()
    {
      Account ac1;
      Account *ac2 = &ac1;
      double rate;
      rate = ac1.rate(); // through an Account object or reference
      rate = ac2->rate(); // through a pointer to an Account object
      rate = Account::rate(); // directly from the class using the scope operator
    
      return 0;
    }

    TOP

  • 相关阅读:
    vue-router 路由拦截 beforeEach 添加静态路由 与 动态添加路由
    elementUI el-upload 根据上传的图片高度,进行自适应宽度
    vue 中 字符串分两行显示
    MySQL中的<=>
    Spring mvc再启动时候会打印项里面的所有路径
    一次解决前后台交互问题
    数据库表分区,分表
    支付宝接口
    打印js中一个对象的所有属性的值
    var
  • 原文地址:https://www.cnblogs.com/xin-le/p/4087981.html
Copyright © 2011-2022 走看看