标签:技术 mamicode 转移 tor apt 纯虚函数 size_t 相关 它的
class Quote {
public:
std::string isbn() const;
virtual double net_price(std::size_t n) const;
virtual void fun(int);
void fun2();
};
class Bulk_quote : public Quote { // 类派生列表
public:
double net_price(std::size_t) const override;
void fun() override; // error:虚函数覆盖必须参数列表和返回值都和基类一样
void fun2() override; // error: 只有虚函数可以声明为override
};
class Quote {
public:
Quote() = default;
Quote(const std::string &book, double sales_price): bookNo(book), price(sales_price) { }
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n) const { return n * price; }
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0.0;
};
class Bulk_quote : public Quote {
public:
Bulk_quote() = default;
Bulk_quote(const std::string&, double, std::size_t, double);
double net_price(std::size_t) const override; // virtual
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
Bulk_quote(const std::string& book, double p,
std::size_t qty, double disc): Quote(book, p), min_qty(qty), discount(disc) { };
Quote item; // 基类对象 Bulk_quote bulk; // 派生类对象 Quote *p = &item; // p指向基类 p = &bulk; // p指向派生类对象bulk的基类部分 Quote &r = bulk; // r引用派生类对象bulk的基类部分
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(); // this->statmem();
}
class Base { /* ... */ } ;
class D1: public Base { /* ... */ }; // Base是D1的直接基类
class D2: public D1 { /* ... */ }; // Base是D2的间接基类,D1是D2的直接基类
class NoDerived final { /* ... */ }; // NoDerived不能被继承
class Base { /* ... */ };
class Last final : Base { /* ... */ }; // Last不能被继承
class Bad : NoDerived { /* ... */ }; // error: NoDerived不能被继承
class Bad2 : Last { /* ... */ }; // error: Last不能被继承
Bulk_quote bulk; // 派生类对象 Quote *itemP = &bulk; // 指向基类的指针
Quote base; // 基类对象 Bulk_quote bulk; // 派生类对象 Quote *itemP = &base; // itemP的静态类型:Quote&,itemP的动态类型:Quote,一样 itemP = &bulk; // itemP的静态类型:Quote&,itemP的动态类型:Bulk_quote,不一样
Quote base; // 基类对象 Bulk_quote* bulkP = &base; // error: 指向派生类的指针 Bulk_quote& bulkRef = base; // error: 派生类的引用 Bulk_quote bulk; // 派生类对象 Quote *itemP = &bulk; // 指向基类的指针可以指向派生类的基类部分 Bulk_quote *bulkP = itemP; // error: bulkP的静态类型:指向派生类的指针,itemP的静态类型:指向基类的指针,无法实现自动转换
Bulk_quote bulk; Quote item(bulk); // 使用Quote::Quote(const Quote&) constructor item = bulk; // 调用Quote::operator=(const Quote&)
double print_total(ostream &os, const Quote &item, size_t n) { // 基类对象的引用 double ret = item.net_price(n); os << "ISBN: " << item.isbn() // calls Quote::isbn << " # sold: " << n << " total due: " << ret << endl; return ret; } Quote base("0-201-82470-1", 50); // 基类对象 print_total(cout, base, 10); // a. 动态绑定到基类对象上,print_total调用 Quote::net_price Bulk_quote derived("0-201-82470-1", 50, 5, .19); // 派生类对象 print_total(cout, derived, 10); // a. 动态绑定到派生类对象上,print_total调用 Bulk_quote::net_price base = derived; // 调用Quote的拷贝赋值函数,拷贝derived的基类部分给base base.net_price(20); // b. 调用Quote::net_price,编译时决定
class A:{
public:
virtual A& fun(int&, char);
};
class B: A{
public:
B& fun(int&, char);
}
class Disc_quote : public Quote { // 抽象基类 public: Disc_quote() = default; Disc_quote(const std::string& book, double price, std::size_t qty, double disc): Quote(book, price), quantity(qty), discount(disc) { } double net_price(std::size_t) const = 0; // 纯虚函数 };
class Bulk_quote : public Disc_quote { // 重构 :重新设计类层级,以便将操作和数据从一个类转移到另一个类。
public:
Bulk_quote() = default;
Bulk_quote(const std::string& book, double price, std::size_t qty, double disc): Disc_quote(book, price, qty, disc) { }
double net_price(std::size_t) const override;
};
class Base {
protected:
int prot_mem;
};
class Sneaky : public Base {
friend void clobber(Sneaky&);
friend void clobber(Base&);
int j;
};
void clobber(Sneaky &s) { s.j = s.prot_mem = 0; } // ok
void clobber(Base &b) { b.prot_mem = 0; } // error:不能直接访问基类的protected成员

class Base {
public:
void pub_mem();
protected:
int prot_mem;
private:
char priv_mem;
};
struct Pub_Derv : public Base {
int f() { return prot_mem; } // ok
char g() { return priv_mem; } // error: 不能访问基类的private成员
};
struct Priv_Derv : private Base {
int f1() const { return prot_mem; } // ok: 可以访问基类的protected成员,对基类成员的访问只由基类本身中的访问说明符控制
};
Pub_Derv d1;
Priv_Derv d2;
d1.pub_mem(); // ok
d2.pub_mem(); // error: Pub_Derv的pub_mem是private成员,不能直接访问
struct Derived_from_Public : public Pub_Derv {
int use_base() { return prot_mem; } // ok
};
struct Derived_from_Private : public Priv_Derv {
int use_base() { return prot_mem; } // error:Pub_Derv的pub_mem是private成员,不能直接访问
};
class Base {
friend class Pal;
};
class Pal {
public:
int f(Base b) { return b.prot_mem; } // ok
int f2(Sneaky s) { return s.j; } // error: Pal不是Sneaky的友元
int f3(Sneaky s) { return s.prot_mem; } // ok: Pal是Base的友元,可以访问Base的派生类的基类部分
};
class Base {
public:
std::size_t size() const { return n; }
protected:
std::size_t n;
};
class Derived : private Base { // 对于类的对象使用者和Derived的派生类来说,从Base继承来的成员都是private,不可访问的
public:
using Base::size; // using改变了Base::size的访问权限,从private到public
protected:
using Base::n; // using改变了Base::n的访问权限,从private到protected
};
class Disc_quote : public Quote {
public:
std::pair<size_t, double> discount_policy() const { return {quantity, discount}; }
};
Bulk_quote bulk; // 派生类对象
Bulk_quote *bulkP = &bulk; // 静态类型和动态类型一样,都是Bulk_quote
Quote *itemP = &bulk; // itemP的静态类型:Quote,动态类型:Bulk_quote
bulkP->discount_policy(); // ok
itemP->discount_policy(); // error:itemP的静态类型是Quote,Quote没有discount_policy成员
struct Base {
int memfcn();
};
struct Derived : Base {
int memfcn(int); // 隐藏了Base的memfcn的成员
};
Derived d;
Base b;
b.memfcn(); // 调用Base::memfcn
d.memfcn(10); // 调用Derived::memfcn
d.memfcn(); // error:编译器首先根据d的静态类型执行名字查找找到Derived中的memfcn成员,然后执行类型匹配发现参数无法匹配无法调用,出错
d.Base::memfcn(); // 调用Base::memfcn
class Base {
public:
virtual int fcn();
};
class D1 : public Base {
public:
int fcn(int); // 和Base::fcn()参数不同,D1会继承Base::fcn()
virtual void f2();
};
class D2 : public D1 {
public:
int fcn(int); // 隐藏了D1::fcn(int)
int fcn(); // 重写虚函数Base::fcn()
void f2(); // 重写虚函数D1::f2
};
//调用虚函数
Base bobj;
D1 d1obj;
D2 d2obj;
Base *bp1 = &bobj, *bp2 = &d1obj, *bp3 = &d2obj;
bp1->fcn(); // 虚函数调用Base::fcn (运行时决定)
bp2->fcn(); // 虚函数调用Base::fcn,因为D1没有重写虚函数fcn()
bp3->fcn(); // 虚函数调用D2::fcn
D1 *d1p = &d1obj;
D2 *d2p = &d2obj;
bp2->f2(); // error:在Base类中名字查找f2,Base没有成员f2
d1p->f2(); // 虚函数调用D1::f2()
d2p->f2(); // 虚函数调用D2::f2()
//调用非虚函数
Base *pb = &d2obj; // 静态类型不一样,动态类型一样
D1 *pd1 = &d2obj;
D2 *pd2 = &d2obj;
pb->fcn(42); // error: Base没有fcn(int)成员
pd1->fcn(42); // 调用D1::fcn(int)
pd2->fcn(42); // 调用D2::fcn(int)
class Base { /* ... */ } ;
class D: public Base {
public:
D(const D& d): Base(d)
/* initializers for members of D */ { /* ... */ }
D(D&& d): Base(std::move(d))
/* initializers for members of D */ { /* ... */ }
};
class Bulk_quote : public Disc_quote {
public:
using Disc_quote::Disc_quote; // 继承Disc_quote的构造函数
double net_price(std::size_t) const;
};
// derived(parms) : base(args) { }
Bulk_quote(const std::string& book, double price, std::size_t qty, double disc): Disc_quote(book, price, qty, disc) { }
【C++ Primer Chapter 15 总结】面向对象编程
标签:技术 mamicode 转移 tor apt 纯虚函数 size_t 相关 它的
原文地址:https://www.cnblogs.com/tristatl/p/14825116.html