static this 数据或函数之前添加,成为静态数据或静态函数
成员函数隐藏参数this,可以直接在成员函数中调用,可以在函数体中出现
静态函数没有this这个隐藏参数,如果要处理数据的话只能处理静态数据
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Account {public : static double m_rate; static void set_rate (const double & x) { m_rate = x; } }; double Account::m_rate = 8.0 ;int main () { Account::set_rate (5.0 ); Account a; a.set_rate (7.0 ); return 0 ; }
c++中单例的写法 private区创建一个静态对象,全局只有一份 将这个类的构造方法放在private区,这样外界无法调用构造函数创建该对象 在public区创建一个静态函数,通过这个函数获取创建的静态对象,达到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class A {public : static A& getInstance (return a;) ; setup () {} private : A (); A (const A& rhs); static A a; }; A::getInstance () A::getInstance ().setup ()
如果外界没有用到a,它也存在,有点浪费,改进:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class A {public : static A& getInstance () ; setup () {} private : A (); A (const A& rhs); }; A& A::getInstance () { static A a; return a; }
对比一下oc的严格单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 Singleton.h @interface Singleton : NSObject @property(nonatomic,strong) NSString *name; +(Singleton*)defaultManager; @end Singleton.m @implementation Singleton //单例类的静态实例对象,因对象需要唯一性,故只能是static类型 static Singleton *defaultManager = nil; /**单例模式对外的唯一接口,用到的dispatch_once函数在一个应用程序内只会执行一次,且dispatch_once能确保线程安全 */ +(Singleton*)defaultManager { static dispatch_once_t token; dispatch_once(&token, ^{ if(defaultManager == nil) { defaultManager = [[self alloc] init]; } }); return defaultManager; } /**覆盖该方法主要确保当用户通过[[Singleton alloc] init]创建对象时对象的唯一性,alloc方法会调用该方法,只不过zone参数默认为nil,因该类覆盖了allocWithZone方法,所以只能通过其父类分配内存,即[super allocWithZone:zone] */ +(id)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t token; dispatch_once(&token, ^{ if(defaultManager == nil) { defaultManager = [super allocWithZone:zone]; } }); return defaultManager; } //自定义初始化方法,本例中只有name这一属性 - (instancetype)init { self = [super init]; if(self) { self.name = @"Singleton"; } return self; } //覆盖该方法主要确保当用户通过copy方法产生对象时对象的唯一性 - (id)copy { return self; } //覆盖该方法主要确保当用户通过mutableCopy方法产生对象时对象的唯一性 - (id)mutableCopy { return self; } //自定义描述信息,用于log详细打印 - (NSString *)description { return [NSString stringWithFormat:@"memeory address:%p,property name:%@",self,self.name]; }
类模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 template <typename T>class complex {public : complex (T r = 0 , T i = 0 ) : re (r), im (i) {} complex& operator += (const complex&); T real () const { return re;} T imag () const { return im;} private : T re, im; friend complex& __doapl (complex*, const complex&); }; { complex<double > c1 (2.1 , 2.2 ) ; complex<int > c2 (1 ,2 ) ; }
模板的使用会造成代码的膨胀,但这是必须的
函数模板 参数类型推导argument deduction
1 2 3 4 5 6 7 template <class T>inline const T& min (const T& a, const T& b) { return b < a ? b : a; } stone r1 (2 ,3 ) , r2 (3 ,4 ) , r3 ;r3 = min (r1, r2);
注意stone类中的运算符重载
这样的设计合理吗? 不管什么类,比大小都是”<“,但是具体到每个类,如何比大小只有每个类自己知道,所以应该由每个类自己去决定(实现),而不是比大小的人(调用者)决定
namespace 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 namespace std {} #include <iostream> using namespace std;int main () { cin << ...; return 0 ; } #include <iostream> using std:cout;int main () { std::cin << ...; cout << ...; return 0 ; } #include <iostream> int main () { std::cin << ...; std::cout << ...; return 0 ; }
using directive:using命令,全部打开 using declaration:using声明,部分打开
其他
operator type () const; 转换函数
explicit complex(…):initialization list{} 特殊的构造函数
pointer-like obj
function-like obj
namespace
template specialization 模板特化
standard library
variadic template (since C++11)
move ctor(since C++11)
rvalue reference(since C++11)
auto (since C++11)
lambda(since C++11)
range-base for loop(since C++11)
unordered containers(since C++11)