C++高效编程守则视情况而变化,取决于使用C++的哪一个部分
#include
template
inline void delete_ptr(T** ptr)
{
if(*ptr)
{
delete *ptr;
*ptr = nullptr;
}
}
class Object
{
public:
virtual ~Object() = 0;
};
//必须为纯虚析构函数提供一份定义
Object::~Object()
{
std::cout << "~Object()" << std::endl;
}
class ChildA : public Object
{
public:
~ChildA(){ std::cout << "~A()" << std::endl;}
};
int main()
{
//Object* p = new Object; //错误,不能实例化
ChildA* a = new ChildA;
delete_ptr(&a);
return 0;
}
Widget& operator=(const Widget& rhs)
{
...
return* this;
}
class Customer
{
public;
...
Customer(const Customer& rhs);
Customer& operator=(const Customer& rhs);
private:
std::string name;
};
Customer::Customer(const Customer& rhs);
{
...
}
Customer& Customer::operator=(const Customer& rhs)
{
...
name = rhs.name;
return *this;
}
class PriorityCustomer : public Customer
{
public:
PriorityCustomer(const PriotyCustomer& rhs);
priorityCustomer& operator=(const PriotyCustomer& rhs);
private:
int priority;
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs):Customer(rhs), priority(rhs.priority)
{
...
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
...
Customer::operator=(rhs);
priority = rhs.priority;
return *this;
}
class WidgetImp1
{
public:
private:
int a, b, c;
std::vector v;
}
class Widget //使用pimpl手法
{
public:
Widget(const Widget& rhs);
Widget& operator=(const Widget& rhs);
{
*pImpl = *(rhs.pImpl);
}
class swap(Widget& other)
{
using std::swap; //
swap(pImpl, other.pImpl); //
}
...
private:
WidgetImpl* pImpl;
}
namespact std{
template<> //表示它是std::的一个全特化版本
void swap(Widget& a, Widget& b) //表示这一特化版本
{ //针对T是Widget而设计
a.swap(b);
}
}
class Person
{
public:
virtual ~Person(){}
virtual string name() const = 0;
virtual string birthDate() const = 0;
virtual string address() const = 0;
static shared_ptr create(const string& name, const string& birthDate,
string& address);
};
class RealPerson:public Person
{
public:
RealPerson(const string& name, const string& birthDate, const string& address)
:m_name(name), m_birthDate(birthDate), m_address(address)
{
}
virtual ~RealPerson()
{
}
string name() const
{
return m_name;
}
string birthDate() const
{
return m_birthDate;
}
string address() const
{
return m_address;
}
private:
string m_name;
string m_birthDate;
string m_address;
};
shared_ptr Person::create(const string& name, const string& birthDate,
string& address)
{
return shared_ptr(new RealPerson(name, birthDate, address));
}
void doSomething()
{
string name = "hei";
string birthDate = "12";
string address = "China";
shared_ptrptr(Person::create(name, birthDate, address));
cout << ptr.get()->name().data() << endl;
cout << ptr.get()->birthDate().data() << endl;
cout << ptr.get()->address().data() << endl;
}
derived classes内的名称会遮掩base classes内的名称。在public继承下从来没人希望如此。
为了让被遮掩的名称再见天日,可以使用using声明式或转交函数。
class Base1
{
public:
virtual void mf1() = 0;
virtual void mf1(int)
{
cout << "base mf1(int)" << endl;
}
virtual void mf2()
{
cout << "base mf2()" << endl;
}
void mf3()
{
cout << "base mf3()" << endl;
}
void mf3(double)
{
cout << "base mf3(double)" << endl;
}
};
class Derived1:public Base1
{
public:
using Base1::mf1;
using Base1::mf3;
virtual void mf1()
{
cout << "Derived1 mf1()" << endl;
}
void mf3()
{
cout << "Derived1 mf3()" << endl;
}
};
void doSomething()
{
Derived1 d1;
d1.mf1();
d1.mf2();
d1.mf3();
d1.mf1(2); //不加using Base1::mf1,则错误,Derived的mf1(),会遮掩掉父类的mf1();
d1.mf3(2.0); //不见using Base1::mf3,则错误
}
由Non-virtual Interface手法实现Template Method模式。
class GameCharacter
{
public:
int healthValue() const
{
... // 事前工作:可锁定互斥器、制作运转日志记录项、验证class约
//束条件、验证函数的先决条件等等
int retVal = doHealthValue(); //真正做些事
... // 事后工作:
return retVal;
}
private:
virtual int doHealthValue() const //derived classes 可重新定义
{
... // 缺省算法
}
};
由Function Pointers现实Strategy模式
class GameCharacter;
int defaultHealthCalc(const GameCharacter& gc);
class GameCharacter
{
public:
typedef int (*HealthCalcFunc)(const GameCharacter&);
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc):healthFunc(hcf)
{
}
int healthValue() const
{
return healthFunc(*this);
}
private:
HealthCalcFunc healthFunc;
};
class EvilBadGuy:public GameCharacter
{
public:
explicit EvilBadGuy(HealthCalcFunc hcf = defaultHealthCalc):GameCharacter(hcf)
{
}
};
int loseHealthQuickly(const GameCharacter&);
int loseHealthSlowly(const GameCharacter&);
EvilBadGuy ebg1(loseHealthQuickly);
EvilBadGuy ebg2(loseHealthSlowly);
class GameCharacter;
int defaultHealthCalc(cosnt GameCharacter& gc);
class GameCharacter
{
public:
typedef std::function HealthCalcFunc;
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc):healthFunc(hcf)
{
}
int healthValue() const
{
return healthFunc(*this);
}
private:
HealthCalcFunc healthFunc;
};
class GameCharacter;
class HealthClacFunc
{
public:
virtual int calc(const GameCharacter& gc) const
{
}
};
HealthCalcFunc defaultHealthCalc;
class GameCharacter
{
public:
explicit GameCharacter(HealthCalcFunc* phcf = &defaultHealthCalc):pHealthCalc(phcf)
{
}
int healthValue() const
{
return pHealthCalc->calc(*this);
}
private:
HealthCalcFunc* pHealthCalc;
}
//嵌套从属类型名称示例:
template
void print2nd(const C& container)
{
if(container.size() >= 2)
{
//在缺省的情况下C::const_iterator不被认为是类型,在嵌套从属关系C::const_iterator前加typename说 明C::const_iterator为类型(使用vs2015,和最新的g++编译,不加typename貌似也能正常工作)
typename C::const_iterator iter(container.begin());
}
}
//一般性规则:任何时候想要在template中指涉一个嵌套从属类型名,就必须在紧邻它的前一个位置放上typename。
//不能使用typename示例
template
class Derived::public Base::Nested //base class list中不允许typename
{
public:
explicit Derived(int x):Base::Nested(x) //mem.init.list中不允许typename
{
typename Base::Nested temp; //嵌套从属名称,需要加typename;
}
};
//接手一个迭代器,为迭代器所指的对象做一份local副本temp;
template
void workWithIterator(IterT iter)
{
typename std::iterator_traits::value_type temp(*iter)
}
std::iterator_traits::value_type :类型为ItetT对象所指之物的类型
可以在derived class templates内通过“this->”指涉base class templates内的成员名称,或由一个明白写出的“base class资格修饰符完成”。
class CompanyA
{
public:
void sendCleartext(const std::string& msg);
void sendEncrypted(const std::string& msg);
};
class CompanyB
{
public:
void sendCleartext(const std::string& msg);
void sendEncrypted(const std::string& msg);
};
class CompanyZ
{
public:
void sendEncrypted(const std::string& msg);
};
class MsgInfo
{
};
template
class MsgSender
{
public:
void sendClear(const MsgInfo& info)
{
std::string msg;
//info->msg
Company c;
c.sendCleartext(msg);
}
void sendSecret(const MsgInfo& info)
{
}
};
//提供一个针对CompanyZ的MsgSender特化版
template<>
class MsgSender //
{
public:
void sendSecret(const MsgInfo& info)
{
}
};
template
class LoggingMsgSender:public MsgSender
{
public:
void sendClearMsg(const MsgInfo& info)
{
//logging begin
sendClear(info); //不能通过编译,编译器知道base class templates有可能被特化。
//logging end;
}
};
template
class LoggingMsgSender:public MsgSender
{
public:
void sendClearMsg(const MsgInfo& info)
{
//logging begin
this->sendClear(info); //成立,假设sendClear将被继承
//logging end;
}
};
template
class LoggingMsgSender:public MsgSender
{
public:
using MsgSender::sendClear; //告诉编译器,请假设sendClear位于base class内
void sendClearMsg(const MsgInfo& info)
{
//logging begin
sendClear(info); //成立
//logging end;
}
};
template
class LoggingMsgSender:public MsgSender
{
public:
void sendClearMsg(const MsgInfo& info)
{
//logging begin
MsgSender::sendClear(info); //成立,假设sendClear将被继承下来
//logging end;
}
};
template
class shared_ptr
{
public:
shared_ptr(shared_ptr const& r);
template
shared_ptr(shared_ptr const& r); //声明泛化copy构造函数,并不会阻止编译器生产默认的copy构造函数。
shared_ptr& operator=(shared_ptr const& r);
template
shared_ptr& operator=(shared_ptr const& r);
};
template
class Rational
{
public:
friend const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator()*rhs.numerator(),
lhs.denominator()*rhs.denominator());
}
};
//对于复杂的函数
template class Rational; //声明
template
const Rational doMultiply(const Rational& lhs,
const Rational& rhs);
template
class Rational
{
public:
friend const Rational operator*(const Rational& lhs,
const Rational& rhs)
{
return doMultiply(lhs, rhs);
}
};
template<...>
class deque
{
public:
class iterator
{
public:
typedef random_access_iterator_tag iterator_category;
...
};
};
template<...>
class list
{
public:
class iterator
{
public:
typedef bidirectional_iterator_tag iterator_category;
...
};
};
//iterator_traits响应iterator class的嵌套式typedef
template
struct iterator_traits
{
typedef typename IterT::iterator_category iterator_category;
...
};
//对于指针(也是一种迭代器)需要提供一个偏特化版本
template
struct iterator_traits
{
typedef random_access_iterator_tag iterator_category;
...
};
//利用重载在编译器检查类型
template
void doAdvance(IterT& iter, DistT d, std::random_access_iterator_tag)
{
iter += d;
}
template
void doAdvance(IterT& iter, DistT d, std::bidirectional_iterator_tag)
{
if(d >= 0)
{
while(d--)
{
++iter;
}
}
else
{
while(d++)
{
--iter;
}
}
}
template
void doAdvance(IterT& iter, DistT d, std::random_access_iterator_tag)
{
iter += d;
}
template
void doAdvance(IterT& iter, DistT d, std::inputs_iterator_tag)
{
if(d < 0)
{
throw std::out_of_range("Negative distance");
}
while(d--)
{
++iter;
}
}
//调用“劳工函数”
template
void advance(IterT& iter, DistT d)
{
doAdvance(iter, d, typename std::iterator_traits::iterator_category());
}
template
struct Factorial
{
enum {value = n * Factorial::value};
};
template<>
struct Factorial<0> //特殊情况:Factorial<0>; 结束递归的条件
{
enum {value = 1};
};
//令class提供自己的set_new_handler和operator new
//需要声明一个类型为new_handler的static成员,用以指向class Widget的new-handler。
class Widget
{
public:
static std::new_handler set_new_handler(std::new_handler p) throw();
static void* operator new(std::size_t size) throw(std::bad_alloc);
private:
static std::new_handler currentHandler;//static成员必须在class定义式以外被定义(除非是const而且是整型)
};
std::new_handler Widget::currentHandler = 0;//在class实现文件内初始化为null
std::new_handler Widget::set_new_handler(std::new_handler p) throw()
{
std::new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
//资源管理类
class NewHandlerHolder
{
explicit NewHandlerHolder(std::new_handler nh):handler(nh)
{}
~NewHandlerHolder()
{
std::set_new_handler(handler);
}
private:
std::new_handler handler;
NewHandlerHolder(const NewHandlerHolder&); //阻止copying
NewHandlerHolder& operator=(const NewHandlerHolder&):
};
void* Widget::operator new(std::size_t size) throw(bad_alloc)
{
NewHandlerHolder h(std::set_new_handler(currentHandler));//安装Widget的new-handler
return ::operator new(size); //分配内存或抛出异常,恢复global new-handler.
}
//使用new-handling
void outOfMem(); //函数声明,此函数在Widget对象分配失败时调用
Widget::set_new_handler(outOfMen); //设定outOfMem为Widget的new-handling函数
Widget* pw1 = new Widget; // 如果内存分配失败,调用outOfMem
std::string* ps = new std::string; //若内存分配失败,调用global new-handling函数(若有)
Widget::set_new_handler(0); //设定Widget专属的new-handling函数为null
Widget* pw2 = new Widget; //若内存分配失败,立刻抛出异常(class Widget并没有专属的new-handling函数)
operator new接受的参数除了一定会有的size_t外还有其它参数,这比那时所谓的placement new。
特别有用的一个“接受一个指针指向对象该被构造之处”
void* operator new(std::size_t, void* pMemory) throw(); //标准库 #include
当写一个placement operator new,请确定也写出对应的placement operator delete。如果没有这样做,你的程序可能会发生隐微而时断时续的内存泄漏。
当声明placement new 和 placement delete,请确定不要无意识地遮掩它们的正常版本。
缺省情况下C++在global作用域内提供以下形式的operator new:
void* operator new(std::size_t) throw(std::bad_alloc); //normal new
void* operator new(std::size_t, void*) throw(); //placement new
void* operator new(std::size_t, const std::nothrow_t&) throw(); //nothrow new
一个简单的做法,建立一个base class,内含所有正常形式的new和delete
class StandardNewDeleteForms
{
public:
//normal new/delete
static void* operator new(std::size_t size) throw(std::bad_alloc)
{
return ::operator new(size);
}
static void operator delete(void* pMemory) throw()
{
::operator delete(pMemory);
}
//placement new/delete
static void* operator new(std::size_t size, void* ptr) throw()
{
return operator new(size, ptr);
}
static void operator delete(void* pMemory, void* ptr) throw()
{
::operator delete(pMemory, ptr);
}
//nothrow new/delete
static void* operator new(std::size_t size, const std::nothrow_t& nt) throw()
{
return ::operator new(size, nt);
}
static void operator delete(void* pMemory, const std::nothrow_t&) throw()
{
::operator delete(pMemory);
}
};
class Widget:public StandardNewDeleteForms
{
public:
using StandardNewDeleteForms::operator new;
using StandaraNewDeleteForms::operator delete;
//添加自定义placement new
static void* operator new(std::size_t size, std::ostream& logStream) throw(std::bad_alloc);
//添加自定义placement delete
static void operator delete(void* pMemory, std::ostream& logStream) throw();
};