zoukankan      html  css  js  c++  java
  • C++面向对象高级编程(四)基础篇

    技术在于交流、沟通,转载请注明出处并保持作品的完整性。

    一.Static

    二.模板类和模板函数

    三.namespace 


     一.Static

    静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“对象(实例)级别”的.

     类级别的成员,先于该类任何对象的存在而存在,它被该类所有的对象共享.

    Static 1.修饰变量,该变量时全局变量,其实静态变量不归属于类中,它的初始化甚至在这个类初始化之前初始化,且静态变量必须初始化,且只会被初始化一次

    1 class Account {
    2 public:
    3     static double m_rate; //这只是声明,它脱离于对象
    4     static void set_rate(const double& x) { m_rate = x; }
    5 };
    6 double Account::m_rate = 8.0;//static变量初始化(定义)

    上面我们可以看到,我声明一个静态变量m_rate,在类中仅仅是声明,第6行才是真正的初始化(其实叫做定义,[定义:写一行代码使他获得内存叫做定义])

    即使你多次初始化m_rate也没有用,因为m_rate只会被初始化一次

    Static 2.修饰成员函数,第4行 就是一个成员函数,他跟静态变量同样不归属与这个类,所以静态函数没有this指针,即静态函数不能调用非静态成员变量

    那么现在现在我们会想一下非静态成员函数如

    1 class complex
    2 {
    3 public:
    4 ...
    5   double real() const { return re; }
    6 ...
    7 }

    上面的real()函数调用的时候

    complex c1,c2,c3;
    cout << c1.real();//c1调用real(); c1就是this
    cout << c2.real();

     编译器会编译成这样

    complex c1,c2,c3;
    cout << complex::real(&c1);//将this(&c1)传递
    cout << complex::real(&c2);

    然后这样

    double real () const { return this->re; }

     红色的this是编译器自动填充的,静态成员函数没有this指针,所以不能作用于非静态成员变量

     调用静态函数的两种方式

    Account::set_rate(5.0); //对象调用
    Account a;
    a.set_rate(7.0);//class name 调用

    二.模板类和模板函数

    1.模板类,下面这个就是模板类,

    template<typename T>
    class complex
    {
    public:
      complex (T r = 0, T i = 0)
        : re (r), im (i)
    {}
    complex& operator += (const complex&);
        real () const { return re; }
    imag () const { return im; } private:
    T re, im;
      friend complex& __doapl (complex*, const complex&);
    };

    模板类会跟你你实际传进的参数来创建出相应的类

    如果你这样调用的话

      complex<double> c1(2.5,1.5);
      complex<int> c2(2,6);

    他实际上出创造出两个类

    //double型
    class
    complex { public: complex (double r = 0, double i = 0) : re (r), im (i) {} complex& operator += (const complex&); real () const { return re; } imag () const { return im; } private: double re, im; friend complex& __doapl (complex*, const complex&); }; //int型 class complex { public: complex (int r = 0, init i = 0) : re (r), im (i) {} complex& operator += (const complex&); real () const { return re; } imag () const { return im; } private: int re, im; friend complex& __doapl (complex*, const complex&); };

    这样做会造成代码膨胀,但是与其实用价值相比,这些代码膨胀可以忽略

    2.函数模板

    class stone
    {
    public:
        stone(int w, int h, int we): _w(w), _h(h), _weight(we){}
        
        bool operator< (const stone& rhs) const
        {
            return _weight < rhs._weight;
        }
        
    private:
        int _w, _h, _weight;
    };

    template <class T>

    inline const T& min(const T& a, const T& b)

    {

      return b < a? b : a;

    }

    当我们调用时

    1 stone r1(2,3), r2(3,3), r3;
    2 stone r1(2,3), r2(3,3), r3;
    3 r3 = min(r1, r2); r3 = min(r1, r2);

    当我们调用到第3行是,编译器会做参数引导 函数模板会被编译成

    inline const T& min(const stone& a, const stone& b)
    {
        return b < a? b : a;//当调用到此处时  b<a 调用者是b 所以b相当于this指针 这样就会自动调用到 stone中的 operator < 函数中
    }

    三.namespace 

    using directive 就是将该命名空间内的所有的对象都开放出来,但是一定要谨慎使用, 尤其在头文件中一定不要声明全局的using namespace,如果你这样做了,所有包含该头文件的都会有这个using namespace

    include <iostream.h>
    using namespace std; //这样之后会开放std命名空间内的所有变量
    int main()
    {
        cin << ...; cin << ...; //使用using namespace后可以省略std::
        cout << ...; cout << ...;
    }

     using declaration 指定开放命名空间

    include <iostream.h>
    using std::cout;//指定开放命名空间,只开放std::cout
    int main()
    {
        std::cin << ...; std::cin << ...;
        cout << ...; cout << ...;
        return 0;
    }

    如有不正确的地方请指正

    参照<<侯捷 C++面向对象高级编程>>

  • 相关阅读:
    安装IIS
    SQL 通过某个字段名称找到数据库中对应的表
    javascript 操作 drop down list
    The project type is not supported by this installationVS2005
    Get 和 Post 简介
    .Net 控件调用 javascript事件
    JQuery检测浏览器版本
    开车要点
    linux shell工程师要求
    memory management
  • 原文地址:https://www.cnblogs.com/LearningTheLoad/p/7302590.html
Copyright © 2011-2022 走看看