原著:www.geocities.jp/ky_webid/cpp
第19章 静态成员
static 关键字的用法:
1.静态全局变量和函数
2.函数内的静态变量,不在栈上,在静态区域
3.类中的静态变量和函数,不在堆上,在静态区域
第20章 Const成员
1.类中const的成员变量无法显示初始化。(无法做字符串长度)
class CStack{ private:static const int STACK_SIZE = 100; int m_data[STACK_SIZE]; };不可!!应对方案为
class CStack{ private:enum{ STACK_SIZE = 100 }; int m_data[STACK_SIZE]; };
class CSample{ public:CSample() : m_num(100){} // m_numを100で初期化 private:const int m_num; };
class CPoint{ public: int GetX() const; }; // constメンバ関数の定义 int CPoint::GetX() const{return m_x;}
const a a1; a a2; a1.x(); a2.x(); //a1调用const版本,a2调用非const版本。5.const写法
const int nValue; //nValue是const
int const nValue; // nValue是const
const char *pContent; //*pContent是const, pContent可变
const (char *) pContent;//pContent是const,*pContent可变
char const * pContent;// *pContent是const, pContent可
char* const pContent; //pContent是const,*pContent可变
const char* const pContent; //pContent和*pContent都是const
char const* const pContent;// pContent和*pContent都是const
mutable的成员变量,可以在类内的const函数中修改。
6.volatile有可能不同步。
7.explicit
C++中, 一个参数构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色。
1 是个构造器 ,2 是个默认且隐含的类型转换操作符。
explicit构造函数是用来防止隐式转换的。请看下面的代码:
class Test1 { public: Test1(int n) { num = n; } //普通构造函数 private: int num; }; class Test2 { public: explicit Test2(int n) { num = n; } //explicit(显式)构造函数 private: int num; }; int main() { Test1 t1 = 12; //隐式调用其构造函数, 成功 Test2 t2 = 12; //编译错误,不能隐式调用其构造函数 Test2 t3(12); //显式调用成功 return 0; }
在类中设置了友元类,可以在那个类中存在本类的成员时,访问这个本类成员的私有成员
// sample.h class CTestFriend; // クラスの前方宣言 // CTestクラス class CTest{ friend class CTestFriend; // CTestFriendクラスは、CTestクラスに自由にアクセスできる public: CTest(int num) : m_num(num){} private: int m_num; }; // CTestクラスのフレンド class CTestFriend{ public:// フレンドである CTestクラスの privateメンバにアクセス int GetFriendNum(CTest& obj) const { return obj.m_num;} }; // main.cpp #include <iostream> #include "Sample.h" int main(){ CTest test(123); CTestFriend test_friend; std::cout << test_friend.GetFriendNum( test ) << std::endl; return 0; }
在类中设置了友元函数,可以在那个函数中,访问这个类的私有成员
class CTest{ friend int GetFriendNum(CTest& obj); // この関数からはCTestクラスのメンバに自由にアクセスできる public:CTest(int num); private:int m_num; };// コンストラクタ CTest::CTest(int num) : m_num(num){}// フレンド関数 int GetFriendNum(CTest& obj){ return obj.m_num; } <iostream> int main(){ CTest obj( 123 ); std::cout << GetFriendNum(obj) << std::endl; return 0; }
第23章 RTTI
CBase base_obj; CSub1 sub1_obj; CSub2 sub2_obj; // ↓ここの3つのどれか1つだけを有効にして実行してみる CBase *p = &base_obj; //CBase *p = &sub1_obj; //CBase *p = &sub2_obj; const type_info& info = typeid( *p ); // 実行時型情報を取得 if( info == typeid( CBase ) ){ std::cout << "CBase" << std::endl; }else if( info == typeid( CSub1 ) ){ std::cout << "CSub1" << std::endl; }else if( info == typeid( CSub2 ) ){ std::cout << "CSub2" << std::endl; }
第24章 强制类型转换
cast包含dynamic_cast,static_cast,reinterpret_cast,const_cast
staic_cast静态强制;1)不能在无关的指针之间进行static类型强制
dynamic_cast动态强制
1)它返回派生类对象的地址;2)它测试基类指针是否指向下一尖括号<>中所指定类型的对象
class B{ public: int m_iNum; virtual void foo(); }; class D:public B{ public: char *m_szName[100]; }; void func(B *pb){ D *pd1 = static_cast<D *>(pb); //报错 D *pd2 = dynamic_cast<D *>(pb); //返回空指针,用以判断是否是对应类型 //基类转子类合法 }