1. 派生类中虚函数的声明必须和基类中的定义方式完全一致,但有一个例外,返回对基类的引用(或指针)的虚函数,派生类的虚函数可以返回基类虚函数返回类型的派生类的引用或指针。
虚函数也可以有默认实参,通常,如果有用在给定调用中的默认实参,该值将在编译时确定。如果一个调用省略了具有默认值的实参,则所用的值由调用该函数的类型定义,与对象的动态类型无关。通过基类的引用或指针调用虚函数时,默认实参为在基类虚函数声明中指定的值,如果通过派生类的引用或指针调用虚函数时,默认实参为在派生类的版本中指定的值。
2. 接口继承与实现继承
Public派生类继承基类的接口,它具有与基类相同的接口。设计良好的类层次中,public派生类的对象可以用在任何需要基类对象的地方。
使用private或protected派生的类不继承基类的接口,这些派生通常被称为实现继承。
3. 派生类可以恢复集成成员的访问级别,但不能是访问级别比基类中原来指定的更严格或更宽松。
class Base{
public:
std::size_t size()const{return n};
protected:
std::size_t n;
};
class Derived:private Base{
public:
using Base::size;
protected:
using Base::n;
};
4. 友元关系不能继承,基类的友元对派生类的成员没有特殊访问权限。如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。
5. 名字冲突与继承
与基类成员同名的派生类成员将屏蔽对基类成员的访问。
在派生类作用域中,派生类成员将屏蔽基类成员,即使函数原型不同,基类成员也会被屏蔽。
struct Base{
int memfcn();
};
struct Drived:Base{
int memfcn(int);
};
Derived d;
Base b;
b.memfcn();
d.memfcn(10);
d.memfcn(); //error
d.Base::memfcn();
6. 继承与虚函数
class Base{
public:
virtual int fcn();
};
class D1:public Base
{
public:
int fcn(int);
};
class D2:public D1
{
public:
int fcn();
int fcn(int);
};
Base bobj;
D1 d1obj;
D2 d2obj;
Base* bp1=&bobj, *bp2=&d1obj,*bp3=&d2obj;
bp1->fcn(); //ok,call Base::fcn
bp2->fcn(); //ok,call Base::fcn
bp3->fcn(); //ok,call D2::fcn
7. 管理指针成员
智能指针
class U_Ptr
{
friend class HasPtr;
int* ip;
size_t use;
U_Ptr(int * p): ip(p),use(1){}
~U_Ptr(){delete ip;}
}
class HasPtr
{
public:
HasPtr(int* p,int i):ptr(new U_Ptr(p)),val(i){}
HasPtr(const HasPtr& orig):ptr(orig.ptr),val(orig.val)
{++ptr->use;}
HasPtr& operator=(const HasPtr&);
~HasPtr(){if(--ptr->use==0)delete ptr;}
int& operator*(){return *ptr->ip;}
int* operator->(){return ptr->ip}
const int& operator*()const {return *ptr->ip;}
const int* operator->()const {return ptr->ip}
int* get_ptr()const{return ptr->ip;}
int get_int()const{return val;}
void set_ptr(int* p){ptr->ip = p;}
void set_int(int i){val = i;}
int get_ptr_val()const{return *ptr->ip;}
void set_ptr_val(int i){*ptr->ip = i;}
private:
U_Ptr* ptr;
int val;
}
HasPtr HasPtr:: operator=(const HasPtr& rhs)
{
++rhs.ptr->use;
if(--ptr->use==0)
delete ptr;
ptr = rhs.ptr;
val = rhs.val;
return *this;
}
值型类
class HasPtr
{
public:
HasPtr(const int& p,int i):ptr(new int(p)),val(i){}
HasPtr(const HasPtr& orig):ptr(new(*orig.ptr)),val(orig.val){}
HasPtr& operator=(const HasPtr&);
~HasPtr(){delete ptr;}
int* get_ptr()const{return ptr;}
int get_int()const{return val;}
void set_ptr(int* p){ptr = p;}
void set_int(int i){val = i;}
int get_ptr_val()const{return *ptr;}
void set_ptr_val(int i){*ptr = i;}
private:
int* ptr;
int val;
}
HasPtr& HasPtroperator=(const HasPtr& rhs)
{
*ptr = *rhs.ptr;
val = rhs.val;
return *this;
}
智能指针第二种计数方法
class Sales_item
{
public:
Sales_item():p(0),use(new std::size_t(1)){}
Sales_item(const Item_base&);
Sales_item(const Sales_item& i):p(i.p),use(i.use)
{++*use;}
~Sales_item(){decr_use();}
Sales_item& operator=(const Sales_item& i);
const Item_base* operator->()const
{
if(p)return p;
else throw std::logic_error(“unbound Sales_item”);
}
cosnt Item_base& operator*()const
{
if(p)return *p;
else throw std::logic_error(“unbound Sales_item”);
}
private:
Item_base* p;
std::size_t* use;
void decr_use()
{if(--*use==0)delete p;}
};
Sales_item& Sales_item::operator=(const Sales_item& rhs)
{
++*ths.use;
decr_use();
p = rhs.p;
use=rhs.use;
return *this;
}
class Item_base
{
public:
virtual Item_base* clone()const{return new Item_base(*this);}
}
class Bulk_item
{
public:
Bulk_item * clone()const{return new Bulk_item (*this);}
}
Sales_item::Sales_item(const Item_base& item)
:p(item.clone()),use(new std::size_t(1))
{
}