1 若是出于某些缘由,须要在const成员函数中修改某一个或几个成员,那么能够将须要修改的成员声明为mutable,例如函数
class A { public: int m_cannotBeModified; mutable int m_needToBeModified; void ModifyMutable() const { m_needToBeModified = 1; //合法 m_cannotBeModified = 1; //不合法 } };
2 若是一个类没有显式声明构造函数,拷贝构造函数,赋值运算符,析构函数,编译器会相应地合成一个,若是类显式定 义了任何一个构造函数,包括拷贝构造函数,编译器就不会再合成构造函数。
3 要阻止一个类对象拷贝或赋值,能够声明一个简单的基类,基类中将拷贝构造函数和赋值运算符声明为private,这样其派生类的拷贝或赋值操做在编译期就能够被检查出来。例如:this
class A { protected: A(){} ~A(){} private: A(const A& a){} A& operator=(const A&a){} }; class B : public A { }; int main() { B b; //B b1(b); //编译不经过 //B b2 = b; //编译不经过 B b3; //b3 = b; //编译不经过 return 0; }
若是B不继承自任何类,直接把其拷贝构造函数和赋值运算符声明为private,并定义,那么类外不能作拷贝或赋值操做, 类内部或友元函数或友元类仍可作拷贝或赋值操做。
若是B不继承自任何类,直接把其拷贝构造函数和赋值运算符声明为private,不提供定义,那么类外不能作拷贝或赋值操做,类内部或友元函数或友元类要作拷贝或赋值操做的话,连接期会发现错误,由于没有提供定义。
4 若是在基类的构造函数中调用虚函数,那么虚函数毫不会降低到派生类阶层,调用的还是基类自己的虚函数,这时虚函数并无表现得像虚函数。派生类对象在基类构造期间,其对象类型就是基类,其运行时类型信息也属于基类,在进入派生类构造函数前毫不会成一个派生类对象。
5 使用引用计数型智能指针shared_ptr能够有效管理资源,但若是使用shared_ptr时出现了环状引用,仍是会致使内存泄露例以下面的代码,程序退出后,new出来的A和new出来的B的引用计数都仍然是1,堆上的内存空间都不会释放。指针
class B; class A { public: shared_ptr<B> m_b; }; class B { public: shared_ptr<A> m_a; }; int main() { shared_ptr<A> a(new A); //new出来的A的引用计数此时为1 shared_ptr<B> b(new B); //new出来的B的引用计数此时为1 a->m_b = b; //B的引用计数增长为2 b->m_a = a; //A的引用计数增长为2 }
再例以下面的代码,主函数退出后,new出来的CCycleRef引用计数为1,内存没法释放:code
class CCycleRef { public: ~CCycleRef() { cout <<"destroying CCycleRef"<<endl; } public: shared_ptr<CCycleRef> selfRef; }; void CycleRefTest() { shared_ptr<CCycleRef> cyclRef(new CCycleRef()); cyclRef->selfRef = cyclRef; } int _tmain(int argc, _TCHAR* argv[]) { CycleRefTest(); return 0; }
解决办法是使用弱智能指针定义类中的智能指针成员,即将类中的shared_ptr换成weak_ptr便可。
6 前置自增运算符返回的是操做数加1后的值,返回的是操做数自己,是一个左值后置自增运算符返回的是操做数加1前的值,其操做数能够理解为值与原操做数相等的一个常量,是一个右值。
重载前自增运算符和后自增运算符时,要保证其语义与全局的前自增运算符和后自增运算符的语义相同,即前自增返回一个左值,后自增返回一个右值。因此重载的前自增运算符一般返回该对象的引用,以支持++++obj这样的操做;重载的后自增运算符一般返回该类的一个常量对象,防止出现obj++++这样的操做。
例以下面的代码:对象
class A { public: A(){ m_num = 0; } A& operator++() { ++m_num; return *this; } const A operator++(int i) { A temp(*this); ++*this; return temp; } public: int m_num; };