c++继承中的构造函数与拷贝控制

#pragma  once
#include <string>
#include <ostream>
#include <iostream>

class Disc_Quote;//Disc_Quote即将被使用,它将是Quote的派生。若只声明,无需写出它的 派生访问列表

class Quote//类在被用作基类之前,必须已经定义,而不仅仅是声明,派生类需要知道基类有什么样的成员
{
public:
	Quote()
	{
		std::cout << "call Quote DefaultConstructor" << std::endl;
	}
	Quote(const std::string &book, double sales_price) :bookno(book), price(sales_price)
	{
		std::cout << "call Quote Constructor" << std::endl;
	}
	Quote(const Quote & rhs)
	{
		bookno = rhs.bookno;
		price = rhs.price;
		std::cout << "call Quote copyConstructor" << std::endl;
	}
	Quote& operator =(const Quote& rhs)
	{
		bookno = rhs.bookno;
		price = rhs.price;
		std::cout << "call Quote operator = " << std::endl;
		return *this;
	}
	std::string isbn()const
	{
		return bookno;
	}

	virtual double net_price(std::size_t n)const
	{
		return n*price;
	}
	virtual void debug()
	{
		std::cout << "bookno :" << bookno << " price" << price << std::endl;
	}
	virtual ~Quote()
	{
		std::cout << "call Quote destructor" << std::endl;
	}
private:
	std::string bookno;
protected://只有派生类能访问
	double price = 0.0;
};

class Disc_Quote :public Quote
{
public:
	Disc_Quote()
	{
		std::cout << "call DiscQuote DefaultConstructor" << std::endl;
	}
	Disc_Quote(const std::string &book, double price, std::size_t qty, double disc) :Quote(book, price),
		quantity(qty), discount(disc)//每个类控制自己成员的初始化部分,同时每个派生类只需要负责自己的直接基类的初始化
	{
		std::cout << "call DiscQuote Constructor" << std::endl;
	}
	//如果不调用基类的拷贝构造函数,则会使用基类的默认构造函数来初始化派生类中的基类部分
	//同时rhs虽然静态类型是Disc_Quote,但是Quote的拷贝构造函数的参数是Quote引用,
	//因此这里存在一个派生类向基类的隐式转换。
	//我在看《c++prime》第15章之前,一直以为只有派生类的指针可以向基类指针转换。
	//但实际
	Disc_Quote(const Disc_Quote&rhs) :Quote(rhs)
	{
		quantity = rhs.quantity;
		discount = rhs.discount;
		std::cout << "call Disc_Quote CopyConstructor" << std::endl;
	}
	Disc_Quote& operator = (const Disc_Quote&rhs)
	{
		//调用基类赋值操作符,无论它是合成的操作还是自定义操作,因为需要处理派生类中的基类部分
		Quote::operator =(rhs);
		quantity = rhs.quantity;
		discount = rhs.discount;
		std::cout << "call Disc_Quote operator = " << std::endl;
		return *this;
	}
	double net_price(std::size_t n) const = 0 ;
	~Disc_Quote()
	{
		std::cout << "call Disc_Quote destructor" << std::endl;
	}
	void debug()override
	{
		Quote::debug();
		std::cout << "quantity:" << quantity << " dicount" << discount << std::endl;
	}
protected:
	std::size_t quantity = 0;
	double discount = 0.0;
};

class Buck_Quote :public Disc_Quote
{
public:
	Buck_Quote()
	{
		std::cout << "call Buck_Quote Constructor" << std::endl;
	}
	~Buck_Quote()
	{
		std::cout << "call Buck_Quote destructor" << std::endl;
	}
	Buck_Quote(const Buck_Quote&rhs):Disc_Quote(rhs)//在构造函数列表调用基类构造函数
	{
		std::cout << "call Buck_Quote CopyConstructor" << std::endl;
	}
	Buck_Quote& operator=(const Buck_Quote&rhs)
	{
		Disc_Quote::operator=(rhs);
		std::cout << "call Buck_Quote operator =" << std::endl;
		return *this;
	}
	Buck_Quote(const std::string &, double, std::size_t, double);
	double net_price(std::size_t n) const override;//重写基类成员
private:
};

double print_total(std::ostream &os, const Quote&item, size_t n);

。。。。。

#include "Quote.h"

Buck_Quote::Buck_Quote(const std::string &book, double p, std::size_t qyy, double disc)
	:Disc_Quote(book, p, qyy, disc)
{
	std::cout << "call Buck_Quote construct" << std::endl;
}

double Buck_Quote::net_price(std::size_t cnt)const
{
	if (cnt>=quantity)
	{
		return cnt*(1 - discount)*price;
	}
	else
	{
		return cnt *price;
	}
}

double print_total(std::ostream &os, const Quote&item, size_t n)
{
	double ret = item.net_price(n);
	os << "isbn" << item.isbn() << " total due " << ret << std::endl;
	return ret;
}

。。。

#include "Quote.h"
#include <iostream>
int main()
{
	Buck_Quote b1("b1", 3, 4, 0.2);
	b1.debug();
	std::cout << "***" << std::endl;
	Quote q1("q1", 3);
	q1.debug();
	std::cout << "***" << std::endl;
	Buck_Quote b2(b1);
	b2.debug();
	std::cout << "***" << std::endl;

	Buck_Quote b3("b3", 5, 7, 0.9);
	b3.debug();
	std::cout << "***" << std::endl;

	b2 = b3;
	b2.debug();
	/*print_total(std::cout, b1, 5);
	print_total(std::cout, q1, 5);*/
	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/sinat_14884161/article/details/54976289