标签:技术 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