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++面向对象高级编程>>

posted @ 2017-08-08 22:12  WangZijian  阅读(403)  评论(0编辑  收藏  举报