只包含类类型或内置类型数据成员、不含指针的类一般可以使用合成操作,复制、赋值或撤销这样的成员不需要特殊控制。具有指针成员的类一般需要定义自己的复制控制来管理这些成员
1.定义派生类复制构造函数
注解:如果派生类显式定义自己的复制构造函数或赋值操作符,则该定义将完全覆盖默认定义。被继承类的复制构造函数和赋值操作符负责对基类成分以及类自己的成员进行复制或赋值。
如果派生类定义了自己的复制构造函数,该复制构造函数一般应显式使用基类复制构造函数初始化对象的基类部分:
class Base { /* ... */ };
class Derived: public Base {
public:
// Base::Base(const Base&) not invoked automatically
Derived(const Derived& d):
Base(d) /* other member initialization */ { /*... */ }
//此处显示使用基类复制构造函数初始化对象的基类部分,若省略基类初始化函数,结果是运行Base的默认构造函数初始化对象的基类部分
};
2.派生类赋值操作符
赋值操作符通常与复制构造函数类似:如果派生类定义了自己的赋值操作符,则该操作符必须对基类部分进行显式赋值。
// Base::operator=(const Base&) not invoked automatically
Derived &Derived::operator=(const Derived &rhs)
{
if (this != &rhs) {
Base::operator=(rhs); // assigns the base part
// do whatever needed to clean up the old value in the derived part
// assign the members from the derived
}
return *this;
}
3.派生类析构函数
析构函数的工作与复制构造函数和赋值操作符不同:派生类析构函数不负责撤销基类对象的成员。编译器总是显式调用派生类对象基类部分的析构函数。每个析构函数只负责清除自己的成员:
class Derived: public Base {
public:
// Base::~Base invoked automatically
~Derived() { /* do what it takes to clean up derived members */ }
};
对象的撤销顺序与构造顺序相反:首先运行派生析构函数,然后按继承层次依次向上调用各基类析构函数4.例子
说了这么多,我们还是看一个例子吧
#include <iostream>
#include <string>
using namespace std;
class Item_base
{
public:
Item_base(const string &book = "", double sales_price = 0.0) : isbn(book), price(sales_price)
{
cout << "Item_base(const string&, double)" << endl;
}
string book() const
{
return isbn;
}
virtual double net_price(size_t cnt)
{
return cnt * price;
}
Item_base(const Item_base &rhs) : isbn(rhs.isbn), price(rhs.price)
{
cout << "Item_base(const Item_base&)" << endl;
}
Item_base& operator = (const Item_base &rhs)
{
isbn = rhs.isbn;
price = rhs.price;
cout << "Item_base& operator = (const Item_base&)" << endl;
return *this;
}
virtual ~Item_base()
{
cout << "~Item_base()" << endl;
}
private:
string isbn;
protected:
double price;
};
class Bulk_item : public Item_base
{
public:
Bulk_item(const string &book = "", double sales_price = 0.0, size_t qty = 0, double disc_rate = 0.0)
: Item_base(book, sales_price), min_qty(qty), discount(disc_rate)
{
cout << "Bulk_item(const string&, double, size_t, double)" << endl;
}
double net_price(size_t cnt)
{
if(cnt > min_qty){
return cnt * price * (1 - discount);
}else
return cnt * price;
}
Bulk_item(const Bulk_item &rhs) : Item_base(rhs), min_qty(rhs.min_qty), discount(rhs,discount)
{
cout << "Bulk_item(const Bulk_item &rhs)" << endl;
}
Bulk_item& operator = (const Bulk_item &rhs)
{
if(this != &rhs){
Item_base::operator = (rhs);
min_qty = rhs.min_qty;
discount = rhs.discount;
}
cout << "Bulk_item& operator = (const Bulk_item&)" << endl;
return *this;
}
virtual ~Bulk_item()
{
cout << "~Bulk_item()" << endl;
}
private:
size_t min_qty;
double discount;
};
void func1(Item_base obj)
{
}
void func2(Item_base &obj)
{
}
Item_base func3()
{
Item_base obj;
return obj;
}
int main()
{
Item_base iobj;
func1(iobj);
func2(iobj);
iobj = func3();
Item_base *p = new Item_base;
delete p;
Bulk_item bobj;
func1(bobj);
func2(bobj);
Bulk_item *q = new Bulk_item;
delete q;
return 0;
}
运行结果如下,并解释如下: