C++ Primer 学习笔记 第十五章面向对象程序设计
527 类的继承和函数绑定
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
string isbn() const{
return "hello world";
};
// virtual function, will be rewrite
virtual double net_price(size_t n) const{
return n;
}
};
// inherit Quote
class Bulk_quote:public Quote{
public:
// rewrite net_price
double net_price(size_t n) const override{
return n/2;
}
};
double print_total(ostream &os, const Quote &item, size_t n){
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << endl;
return ret;
}
int main() {
Quote basic;
Bulk_quote bulk;
print_total(cout, basic, 20); // ISBN: hello world # sold: 20 total due: 20
print_total(cout, bulk, 20); // ISBN: hello world # sold: 20 total due: 10
}
529 基类和派生类
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string&, double, size_t, double){};
double net_price(size_t) const override{return discount;};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
cout << basic.isbn() << endl;
Bulk_quote bulk("rgd", 10, 3, 10);
bulk.isbn()
}
530 派生类对象及派生类向基类转换
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string&, double, size_t, double){};
double net_price(size_t) const override{return discount;};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
cout << basic.isbn() << endl;
Bulk_quote bulk("rgd", 10, 3, 10);
Quote *p = &basic;
// 派生类对象转基类
p = &bulk;
Quote &r = bulk;
}
531 派生类的构造函数
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc):Quote(book, p), min_qty(qty), discount(disc){};
double net_price(size_t) const override{return price*discount;};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
cout << basic.isbn() << endl;
Bulk_quote bulk("rgd", 20, 3, 0.8);
cout << bulk.isbn() << " " << bulk.net_price(5) << endl; // 16
}
531 派生类使用基类成员
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc):Quote(book, p), min_qty(qty), discount(disc){};
double net_price(size_t) const override;
private:
size_t min_qty = 0;
double discount = 0.0;
};
double Bulk_quote::net_price(size_t cnt) const {
if (cnt>=min_qty){
return cnt*(1-discount)*price;
} else{
return cnt*price;
}
}
int main() {
Quote basic("avc", 20);
cout << basic.isbn() << endl;
Bulk_quote bulk("rgd", 20, 3, 0.2);
cout << bulk.isbn() << " " << bulk.net_price(5) << endl; // 80
}
532 继承与静态成员
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
public:
static void statmem();
};
class Derived:public Base{
void f(const Derived&);
};
void Derived::f(const Derived &derived_obj) {
Base::statmem();
Derived::statmem();
derived_obj.statmem();
statmem();
}
int main() {
}
533 添加final关键字,使得类不能够被继承
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class NoDerived final {
};
class Base{
};
class Last final : Base {
};
// error: marked final
//class Bad:NoDerived{
//
//};
// error: marked final
//class Bad2:Last{
//
//};
int main() {
}
535 只能从派生类到基类转换
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc):Quote(book, p), min_qty(qty), discount(disc){};
double net_price(size_t) const override{return price*discount;};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
Bulk_quote bulk("rgd", 20, 3, 0.8);
Quote base;
// error: base can not convert into children
// Bulk_quote* bulkP = &base;
// Bulk_quote& bulkRef = base;
Quote *itemP = &bulk; // correct, children can convert into base
// Bulk_quote *bulkP = itemP; // error
}
535 使用派生类去构造基类部分内容被切割掉
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc):Quote(book, p), min_qty(qty), discount(disc){};
double net_price(size_t) const override{return price*discount;};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
Bulk_quote bulk("rgd", 20, 3, 0.8);
Quote item(bulk);
cout << item.net_price(2); // 2*20
item = bulk;
}
538 使用override令编译器检查重写函数的形参和虚函数形参是否一样
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
struct B{
virtual void f1(int) const;
virtual void f2();
void v3();
};
struct D1:B{
void f1(int) const override;
// void f2(int) override;
};
int main() {
}
538 加了关键字final后不能被重写
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
struct B{
virtual void f1(int) const;
virtual void f2();
void v3();
};
struct D2:B{
void f1(int) const final;
};
struct D3:D2{
void f2();
// error can not override final
// void f1(int) const;
};
int main() {
}
539 明确指定调用的类方法
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc):Quote(book, p), min_qty(qty), discount(disc){};
double net_price(size_t n) const override{
return Quote::net_price(n)*discount;
};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
Bulk_quote bulk("rgd", 20, 3, 0.8);
cout << bulk.net_price(10) << endl;
// double undiscounted = bulk->Quote::net_price(10);
}
15.11
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
virtual void debug(){
cout << "bookNo: " << bookNo << " price: " << price << endl;
};
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double disc):Quote(book, p), min_qty(qty), discount(disc){};
double net_price(size_t n) const override{
return Quote::net_price(n)*discount;
};
void debug() override{
Quote::debug();
cout << "min_qty: " << min_qty << " discount: " << discount << endl;
}
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Quote basic("avc", 20);
Bulk_quote bulk("rgd", 20, 3, 0.8);
cout << bulk.net_price(10) << endl;
// double undiscounted = bulk->Quote::net_price(10);
bulk.debug();
}
541 纯虚以及多级继承
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
virtual void debug(){
cout << "bookNo: " << bookNo << " price: " << price << endl;
};
private:
string bookNo;
protected:
double price = 0.0;
};
class Disc_quote:public Quote{
public:
Disc_quote()=default;
Disc_quote(const string& book, double price, size_t qty,
double disc): Quote(book, price), quantity(qty), discount(disc){};
double net_price(size_t) const=0;
private:
size_t quantity = 0;
double discount = 0;
};
// inherit Quote
class Bulk_quote: public Disc_quote{
public:
Bulk_quote() = default;
Bulk_quote(const string &book, double price, size_t qty, double disc):Disc_quote(book, price, qty, disc){}
double net_price(size_t) const override;
void debug() override{
Quote::debug();
cout << "min_qty: " << min_qty << " discount: " << discount << endl;
}
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main() {
Bulk_quote bulk("rgd", 20, 3, 0.8);
cout << bulk.net_price(10) << endl;
// double undiscounted = bulk->Quote::net_price(10);
bulk.debug();
}
543 protect只能通过派生类成员函数,或者友元里面的派生类形参访问
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
protected:
int prot_mem;
};
class Sneaky:public Base{
friend void clobber(Sneaky&);
friend void clobber(Base&);
int j;
void debug(){
// 通过派生类成员函数访问
prot_mem = 10;
}
};
// correct 可以通过派生类形参访问
void clobber(Sneaky &s){
s.j=s.prot_mem=0;
}
// error 不能通过基类形参访问
//void clobber(Base& b){
// b.prot_mem=0;
//}
int main() {
}
544 受保护继承
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
public:
void pub_mem();
protected:
int prot_mem;
private:
char priv_mem;
};
struct Pub_Derv:public Base{
int f(){return prot_mem;}
// private number is not accessible
// char g(){return priv_mem}
};
struct Priv_Derv:private Base{
int f1() const {return prot_mem;}
};
int main() {
Pub_Derv d1;
Priv_Derv d2;
d1.pub_mem();
// pub_mem() not accessible because of private Base in declaration of Priv_Derv
// struct Priv_Derv:private Base
// d2.pub_mem();
}
545 友元不能继承
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
friend class Pal;
protected:
int prot_num = 1;
private:
int priv = 1;
};
class Sneaky:public Base{
protected:
int j;
};
class Pal{
public:
int f(Base b){return b.prot_num;};
// error Pal is not friend of Sneaky
// int f2(Sneaky s) {return s.j;};
int f3(Sneaky s){return s.prot_num;};
};
//class D2:public Pal{
//public:
// int mem(Base b){
// return b.prot_mem;
// }
//};
int main() {
}
546 using关键字改变private继承的可访问性
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
public:
size_t size() const{return n;}
protected:
size_t n;
private:
size_t priv;
};
class Derived:private Base{
public:
using Base::size;
protected:
using Base::n;
// error using is not useless for private number
//private:
// using Base::priv
};
int main() {
}
15.18-15.19
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
public:
void pub_mem();
protected:
int prot_mem=2;
private:
char priv_mem=4;
};
struct Pub_Derv:public Base{
int f(){return prot_mem;}
// private number is not accessible
// char g(){return priv_mem}
void memfcn(Base &b){
b = *this;
}
};
struct Priv_Derv:private Base{
int f1() const {return prot_mem;}
void memfcn(Base &b){
b = *this;
}
};
struct Prot_Derv:protected Base{
int f2() const {return prot_mem;}
void memfcn(Base &b){
b = *this;
}
};
struct Derived_from_public:public Pub_Derv{
int use_base() {return prot_mem;}
void memfcn(Base &b){
b = *this;
}
};
struct Derived_from_private:public Priv_Derv{
int use_base(){return 0;};
void memfcn(Base &b){
b = *this;
}
};
int main() {
Pub_Derv d1;
Priv_Derv d2;
Prot_Derv d3;
Derived_from_public dd1;
Derived_from_private dd2;
Base b;
d1.memfcn(b);
d2.memfcn(b);
}
548 同名变量的处理方法
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
struct Base{
Base():mem(0){}
protected:
int mem;
};
struct Derived:Base{
Derived(int i):mem(i){}
int get_mum(){return mem;}
int get_base_mum() {return Base::mem;}
protected:
int mem;
};
int main() {
Derived d(42);
cout << d.get_mum() << endl;
cout << d.get_base_mum() << endl;
}
549 函数名比形参列表优先级更高
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
struct Base{
public:
int memfcn(){return 42;};
};
struct Derived:Base{
int memfcn(int){
return 84;
}
};
int main() {
Derived d;
Base b;
b.memfcn();
d.memfcn(10);
// error memfcn() in Base is hidden here
// d.memfcn()
d.Base::memfcn();
}
550 虚函数与作用域
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
public:
virtual int fcn(){
return 0;
};
};
class D1:public Base{
public:
int fcn(int){
return 1;
};
virtual string f2(){string str = "D1"; return str;};
};
class D2:public D1{
public:
int fcn(int){return 2;};
int fcn(){return 2;};
string f2(){string str = "D2"; return str;};
};
int main() {
Base bobj; D1 d1obj; D2 d2obj;
Base *bp1=&bobj, *bp2 = &d1obj, *bp3 = &d2obj;
cout << bp1->fcn() << endl << bp2->fcn() << endl << bp3->fcn() <<endl; // 0 0 2
D1 *d1p = &d1obj; D2 *d2p = &d2obj;
// cout << bp2->f2();
cout << d1p->f2() << endl << d2p->f2(); // D1 D2
Base *p1 = &d2obj; D1 *p2 = &d2obj; D2 *p3 = &d2obj;
// cout << p1->fcn(42); error
cout << p2->fcn(42) << endl << p3->fcn(42);
}
15.23
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
public:
virtual int fcn(){
return 0;
};
};
class D1:public Base{
public:
int fcn(){
return 1;
};
virtual string f2(){string str = "D1"; return str;};
};
class D2:public D1{
public:
int fcn(int){return 2;};
int fcn(){return 2;};
string f2(){string str = "D2"; return str;};
};
int main() {
Base bobj; D1 d1obj; D2 d2obj;
Base *bp1=&bobj, *bp2 = &d1obj, *bp3 = &d2obj;
cout << bp1->fcn() << endl << bp2->fcn() << endl << bp3->fcn() <<endl; // 0 1 2
D1 *d1p = &d1obj; D2 *d2p = &d2obj;
// cout << bp2->f2();
cout << d1p->f2() << endl << d2p->f2(); // D1 D2
Base *p1 = &d2obj; D1 *p2 = &d2obj; D2 *p3 = &d2obj;
// cout << p1->fcn(42); error
cout << "p2->fcn(42)" << endl << p3->fcn(42); //2
}
554 合成拷贝控制的继承
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class B{
public:
B();
B(const B&)=delete;
};
class D:public B{
};
int main() {
D d;
// 拷贝控制函数被删除了,所以不合法
//D d2(d);
//D d3(move(d))
}
555 定义派生类的移动构造函数
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
};
class D:public Base{
public:
// Base(d) match copy constructor in Base, use d to initialize base
D(const D& d): Base(d){}
// 可以运行,但是实际没意义,因为新对象中的数据copy了d中的,但是基类使用了默认的构造函数,没有使用d中的数值,显得很奇怪
// D(const D &d){}
D(D&& d): Base(move(d)){}
};
int main() {
}
556 派生类的赋值运算符
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
};
class D:public Base{
public:
// Base(d) match copy constructor in Base, use d to initialize base
D(const D& d): Base(d){}
// 可以运行,但是实际没意义,因为新对象中的数据copy了d中的,但是基类使用了默认的构造函数,没有使用d中的数值,显得很奇怪
// D(const D &d){}
D(D&& d): Base(move(d)){}
D &D::operator=(const D &rhs){
Base::operator=(rhs);
return *this;
};
};
int main() {
}
556 派生类析构函数
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Base{
};
class D:public Base{
public:
// Base(d) match copy constructor in Base, use d to initialize base
D(const D& d): Base(d){}
// 可以运行,但是实际没意义,因为新对象中的数据copy了d中的,但是基类使用了默认的构造函数,没有使用d中的数值,显得很奇怪
// D(const D &d){}
D(D&& d): Base(move(d)){}
D &D::operator=(const D &rhs){
Base::operator=(rhs);
return *this;
};
~D(){}
};
int main() {
}
557 继承基类的构造函数
构造函数默认是,不能被继承,如果需要继承构造函数,需要用到using关键字
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
virtual void debug(){
cout << "bookNo: " << bookNo << " price: " << price << endl;
};
private:
string bookNo;
protected:
double price = 0.0;
};
class Disc_quote:public Quote{
public:
Disc_quote()=default;
Disc_quote(const string& book, double price, size_t qty,
double disc): Quote(book, price), quantity(qty), discount(disc){};
double net_price(size_t) const=0;
private:
size_t quantity = 0;
double discount = 0;
};
// inherit Quote
class Bulk_quote: public Disc_quote{
public:
Bulk_quote() = default;
// Bulk_quote(const string &book, double price, size_t qty, double disc):Disc_quote(book, price, qty, disc){}
// 用using, 继承构造函数,等于上面那一句
using Disc_quote::Disc_quote;
double net_price(size_t) const override;
void debug() override{
Quote::debug();
cout << "min_qty: " << min_qty << " discount: " << discount << endl;
}
private:
size_t min_qty = 0;
double discount = 0.0;
};
558 把派生类存入基类的容器中
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double dis): Quote(book, p), min_qty(qty), discount(dis){}
double net_price(size_t n) const override{
return n*price*discount;
};
private:
size_t min_qty = 0;
double discount = 0.0;
};
int main(){
vector<Quote> basket;
basket.push_back(Quote("abc", 10));
basket.push_back(Bulk_quote("eft", 10, 3, 0.8));
// call net_price() in Quote but not Disc_quote
cout << basket.back().net_price(2) << endl; // 20
vector<shared_ptr<Quote>> basket1;
basket1.push_back(make_shared<Quote>("abc", 10));
basket1.push_back(make_shared<Bulk_quote>("efg", 10, 3, 0.8));
cout << basket1.back()->net_price(2) << endl; // 16
return 0;
}
561 模拟虚拷贝
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
using namespace std;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price){}
string isbn() const {return bookNo;};
virtual double net_price(size_t n) const{return n*price;}
virtual ~Quote()=default;
virtual Quote* clone() const & {return new Quote(*this);};
virtual Quote* clone() const && {return new Quote(move(*this));};
private:
string bookNo;
protected:
double price = 0.0;
};
// inherit Quote
class Bulk_quote: public Quote{
public:
Bulk_quote() = default;
Bulk_quote(const string& book, double p, size_t qty, double dis): Quote(book, p), min_qty(qty), discount(dis){}
double net_price(size_t n) const override{
return n*price*discount;
};
Bulk_quote* clone() const &{return new Bulk_quote(*this);};
Bulk_quote* clone() && {return new Bulk_quote(move(*this));};
private:
size_t min_qty = 0;
double discount = 0.0;
};
class Basket{
public:
void add_item(const Quote& sale){
items.insert(shared_ptr<Quote>(sale.clone()));
}
void add_item(Quote&& sale){
items.insert(shared_ptr<Quote>(move(sale).clone()));
}
double total_receipt(ostream&) const;
private:
static bool compare(const shared_ptr<Quote> &lhs, const shared_ptr<Quote> &rhs){
return lhs->isbn() < rhs->isbn();
}
multiset<shared_ptr<Quote>, decltype(compare)*> items{compare};
};
int main(){
return 0;
}
562-574 类的完整例子,(未成功运行)
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
using namespace std;
using line_no = vector<string>::size_type;
class QueryResult{
friend ostream& print(ostream&, const QueryResult&);
public:
QueryResult(string s,
shared_ptr<set<line_no>> p,
shared_ptr<vector<string>> f): sought(s), lines(p), file(f){}
private:
string sought;
shared_ptr<set<line_no>> lines;
shared_ptr<vector<string>> file;
};
string make_plural(size_t num, const string& input, const string& suffix){
return (num > 1)? input+suffix:input;
}
ostream &print(ostream & os, const QueryResult &qr){
os << qr.sought << " occurs " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
for (auto num:*qr.lines){
os << "\t(line " << num+1 << ") " << *(qr.file->begin()+num) << endl;
}
return os;
}
class TextQuery{
public:
TextQuery(ifstream &);
QueryResult query(const string&) const;
private:
shared_ptr<vector<string>> file;
map<string, shared_ptr<set<line_no>>> wm;
};
TextQuery::TextQuery(ifstream &is): file(new vector<string>) {
string text;
while (getline(is, text)){
file->push_back(text);
int n = file->size() - 1;
istringstream line(text);
string word;
while (line>>word){
auto &lines = wm[word];
if (!lines)
lines.reset(new set<line_no>);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const string &sought) const {
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc = wm.find(sought);
if (loc==wm.end()){
return QueryResult(sought, nodata, file);
} else{
return QueryResult(sought, loc->second, file);
}
}
class Query_base{
friend class Query;
protected:
// using line_no = TextQuery::line_no;
virtual ~Query_base() = default;
private:
virtual QueryResult eval(const TextQuery&) const=0;
virtual string rep() const=0;
};
class Query{
friend Query operator~(const Query&);
friend Query operator|(const Query&, const Query&);
friend Query operator&(const Query&, const Query&);
public:
Query(const string&);
QueryResult eval(const TextQuery&t) const{
return q->eval(t);
}
string rep() const {return q->rep();}
private:
Query(shared_ptr<Query_base> query):q(query){}
shared_ptr<Query_base> q;
};
ostream & operator<<(ostream &os, const Query &query){
return os<<query.rep();
}
class WordQuery:public Query_base{
friend class Query;
WordQuery(const string &s):query_word(s){}
QueryResult eval(const TextQuery &t) const {
return t.query(query_word);
}
string rep() const {return query_word;}
string query_word;
};
inline Query::Query(const string &s):q(new WordQuery(s)){}
class NotQuery:public Query_base{
friend Query operator~(const Query&);
NotQuery(const Query &q):query(q){}
string rep() const {return "~(" + query.rep() + ")";}
QueryResult eval(const TextQuery&) const;
Query query;
};
inline Query operator~(const Query &operand){
return shared_ptr<Query_base>(new NotQuery(operand));
}
class BinaryQuery:public Query_base{
protected:
BinaryQuery(const Query &l, const Query &r, string s):lhs(l), rhs(r), opSym(s){}
string rep() const{
return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")";
}
Query lhs, rhs;
string opSym;
};
class AndQuery:public BinaryQuery{
friend Query operator&(const Query&, const Query&);
AndQuery(const Query &left, const Query &right): BinaryQuery(left, right, "&"){}
QueryResult eval(const TextQuery&) const;
};
inline Query operator&(const Query &lhs, const Query &rhs){
return shared_ptr<Query_base>(new AndQuery(lhs, rhs));
}
class OrQuery:public BinaryQuery{
friend Query operator|(const Query&, const Query&);
OrQuery(const Query &left, const Query &right): BinaryQuery(left, right, "|"){}
QueryResult eval(const TextQuery&) const;
};
inline Query operator|(const Query &lhs, const Query &rhs){
return shared_ptr<Query_base>(new OrQuery(lhs, rhs));
}
QueryResult OrQuery::eval(const TextQuery & text) const {
auto right = rhs.eval(text), left = lhs.eval(text);
auto ret_lines = make_shared<set<line_no>>(left.begin(), left.end());
ret_lines->insert(right.begin(), right.end());
return QueryResult(rep(), ret_lines, left.get_file());
}
QueryResult AndQuery::eval(const TextQuery &text) const {
auto left=lhs.eval(text),right=rhs.eval(text);
auto ret_lines = make_shared<set<line_no>>();
set_intersection(left.begin(), left.end(),
right.begin(), right.end(),
inserter(*ret_lines, ret_lines->begin()));
return QueryResult(rep(), ret_lines,left.get_file());
}
QueryResult NotQuery::eval(const TextQuery &text) const {
auto result = query.eval(text);
auto ret_lines = make_shared<set<line_no>>();
auto beg = result.begin(), end = result.end();
auto sz = result.get_file()->size();
for (size_t n=0; n!=sz; ++n){
if (beg==end || *beg!=n){
ret_lines->insert(n);
}else if(beg!=end){
++beg;
}
}
return QueryResult(rep(), ret_lines, result.get_file());
}
int main(){
}