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