首页 > 代码库 > 【足迹C++primer】54、继承类的范围,构造函数和拷贝控制
【足迹C++primer】54、继承类的范围,构造函数和拷贝控制
继承类的范围,构造函数和拷贝控制
当用派生类执行函数的时候,首先会在当前的类里面找
如果找不到就一级一级地往上找。
如果找不到就一级一级地往上找。
Name Lookup Happens at Compile Time
class Quote { public: Quote()=default; Quote(const string &book, double sales_price):bookNo(book), price(sales_price) {cout<<"Quote gouzhao function"<<endl;} string isbn() const {return bookNo;} //返回指定数量的项目总销售价格 //派生类将重写应用不同的折扣算法 virtual double net_price(size_t n) const {return n*price;} virtual ~Quote()=default; //动态链接析构函数 private: string bookNo; //这本书的isbn号 protected: double price=0.0; //不打折的价格 }; 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) {cout<<"Bulk_quote construct function"<<endl;} //重写虚函数 double net_price(size_t n) const override {cout<<"double net_price(size_t)"<<endl; return n*price;} //再次说明,请声明函数后一定要记得定义它,不然我这是出了各种莫名其妙的错误! // ~Bulk_quote2(){cout<<"~Bulk_quote2()"<<endl;} ///-------------------------------- pair<size_t, double> discount_policy() const {return {min_qty, discount};} private: size_t min_qty=0; double discount=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) {cout<<"Disc_quote构造函数"<<endl;} double net_price(size_t) const = 0; //纯虚函数 ///------------------------------------------------- pair<size_t, double> discount_policy() const {return {quantity, discount};} protected: size_t quantity=0; double discount=0.0; }; void fun1() { Bulk_quote bulk; Bulk_quote *bulkP=&bulk; Quote *itemP=&bulk; bulkP->discount_policy(); //好的这是一个指针类似(*bulkP).discount_policy() // item->discount_policy(); error:Quote里面没有这个成员 }
Name Collisions and Inheritance(名字冲突的时候继承)
struct Base { Base():mem(0) {} protected: int mem; }; struct Derived : Base { Derived(int i) : mem(i) {} //这里初始化的是Derived的mem用i,而Base::mem是默认初始化的 int get_mem() { return mem; } //返回Derived::mem protected: int mem; //吧base的mem隐藏起来 }; void fun2() { Derived d(42); cout<<d.get_mem()<<endl; //输出42 }
使用作用域操作符使用隐藏的成员
除了重写继承的虚函数的派生类,通常
不应使用基类中定义的名字。
不应使用基类中定义的名字。
As Usual, Name Lookup Happens before Type Checking
struct Base2 { Base2():mem(0) {} int memfcn() {} protected: int mem; }; struct Derived2 : Base2 { Derived2()=default; Derived2(int i) : mem(i) {} //这里初始化的是Derived的mem用i,而Base::mem是默认初始化的 int get_mem() { return mem; } //返回Derived::mem int memfcn(int) {} //吧Base2中的memfcn隐藏了 protected: int mem; //吧base的mem隐藏起来 }; void fun3() { Derived2 d; Base2 b; b.memfcn(); //----->Base的Base::memfcn() d.memfcn(10); //----->Derived的Derived::memfcn() // d.memfcn(); error:这个Derived里面继承Base里面的memfcn被隐藏了 d.Base2::memfcn(); //ok:调用Base::memfcn }
Virtual Functions and Scopeclass Base3
{
public:
virtual int fcn() {cout<<"Base3--->virtual int fcn()"<<endl;}
};
class D1 : public Base3
{
public:
int fcn(int){cout<<"D1--->int fcn(int)"<<endl;} //这个是隐藏了fcn不叫override
virtual void f2(){cout<<"D1--->virtual void f2()"<<endl;}
};
class D2 : public D1
{
public:
int fcn(int){cout<<"D2--->int fcn(int)"<<endl;} //这个是隐藏,没有override在D1这个不是虚函数
int fcn(){cout<<"D2--->int fcn()"<<endl;} //是覆盖,override
void f2(){cout<<"D2--->void f2()"<<endl;} //覆盖,virtual f2 from D1
};
void fun4()
{
Base3 b3obj; D1 d1obj; D2 d2obj;
Base3 *b3p1=&b3obj, *b3p2=&d1obj, *b3p3=&d2obj;
b3p1->fcn(); //这个调用了Base3::fcn
b3p2->fcn(); //调用Base3::fcn
b3p3->fcn(); //调用D2::fcn
D1 *d1p=&d1obj; D2 *d2p=&d2obj;
// b3p2->f2(); error:Base没有f2!!注意是Base而不是D1,因为*b3p2的类型是Base多余部分没有拷贝
d1p->f2(); //D1--->virtual void f2()
d2p->f2(); //D2--->void f2()
Base3 *p1=&d2obj; D1 *p2=&d2obj; D2 *p3=&d2obj;
// p1->fcn(42); error:Base3没有fcn(int)函数
p2->fcn(42); //D1--->int fcn(int)
p3->fcn(42); //D2--->int fcn(int)
}
构造函数和拷贝控制
Virtual Destructors(虚析构函数)
void fun5()
{
Quote *itemP=new Quote;
delete itemP;
itemP=new Bulk_quote;
delete itemP;
}
15.7.2. Synthesized Copy Control and Inheritance
Base Classes and Deleted Copy Control in the Derived
class B
{
public:
B(){cout<<"B()构造函数"<<endl;}
B(const B&)=delete; //这个函数的意思是,这个类不能调用这个函数,默认的都不行
};
class D : public B
{
//什么都没有!!!
};
void fun6()
{
D d;
// D d2(d); error:这个会默认调用了B的B(const B&)但是这个是delete了的
// D d3(std::move(d)); error:同上
}
Move Operations and Inheritance(移动操作与继承)
哎!大家一定要学好英语啊,我是以前不能长期坚持搞得现在英语真是“阴雨”
用的翻译软件,╮(╯▽╰)╭翻译的什么玩意,有的我自己都看不懂,读不通
class Quote2
{
public:
Quote2()=default; //默认构造函数
Quote2(const string &book, double sales_price):bookNo(book), price(sales_price)
{cout<<"Quote gouzhao function"<<endl;}
//拷贝函数
Quote2(const Quote2&)=default;
Quote2(Quote2&&)=default;
//拷贝赋值运算符,和移动赋值运算符
Quote2& operator=(const Quote2&)=default;
Quote2& operator=(Quote2&&)=default;
//析构函数
virtual ~Quote2()=default; //动态链接析构函数
string isbn() const {return bookNo;}
//返回指定数量的项目总销售价格
//派生类将重写应用不同的折扣算法
virtual double net_price(size_t n) const {return n*price;}
private:
string bookNo; //这本书的isbn号
protected:
double price=0.0; //不打折的价格
};
15.7.3. Derived-Class Copy-Control Members
派生类拷贝控制成员
当派生类定义了一个复制或移动操作,那么这个操作符将负责整个类的相应操作
还包括基类的成员的相应操作
定义一个派生拷贝或移动构造函数
默认情况下,基类的默认构造函数初始化基类部分
派生的对象。如果我们想要复制(或移动)基类部分,我们必须
显式使用复制(或移动)在对基类构造函数
派生的构造函数初始化列表。
这里我就不给大家定义了,书上给的很泛,没什么意义
class Base { /* ... */ } ;
class D: public Base {
public:
// by default, the base class default constructor initializes the base part of an object
// to use the copy or move constructor, we must explicitly call that
// constructor in the constructor initializer list
D(const D& d): Base(d) // copy the base members
{ /* ... */ }//initializers for members of D
D(D&& d): Base(std::move(d)) // move the base members
/* initializers for members of D / { /* ... */ }
};
// Base::operator=(const Base&) is not invoked automatically
D &D::operator=(const D &rhs)
{
Base::operator=(rhs); // assigns the base part
// assign the members in the derived class, as usual,
// handling self-assignment and freeing existing resources as appropriate
return *this;
}
class D: public Base {
public:
// Base::~Base invoked automatically
~D() { /* do what it takes to clean up derived members / }
};
析构基类会自动进行!!!但是{}里面的清理对象还是都要写,基类已经写delete了的就会自动调用基类析构函数时调用!!
15.7.4.继承析构函数
在新标准下,一个派生类可以调用基类的构造函数
class Bulk_quote2 : public Disc_quote
{
public:
using Disc_quote::Disc_quote;
//构造函数等价于
/*
Bulk_quote(const string & book, double price, size_t qty, double disc)
: Disc_quote(book, price, qty, disc){}
*/
double net_price(size_t n) const {cout<<"Bulk_quote2,net_price"<<endl; return n*price;}
};
继承构造函数的特点
好吧书上一堆“阴雨”!!!~~~~
the all code !!
/**
* 功能:继承类的范围,构造函数和拷贝控制
* 时间:2014年7月22日07:53:20
* 作者:cutter_point
*/
#include<iostream>
#include<algorithm>
using namespace std;
/*
当用派生类执行函数的时候,首先会在当前的类里面找
如果找不到就一级一级地往上找。
*/
/**
Name Lookup Happens at Compile Time
*/
class Quote
{
public:
Quote()=default;
Quote(const string &book, double sales_price):bookNo(book), price(sales_price)
{cout<<"Quote gouzhao function"<<endl;}
string isbn() const {return bookNo;}
//返回指定数量的项目总销售价格
//派生类将重写应用不同的折扣算法
virtual double net_price(size_t n) const {return n*price;}
virtual ~Quote()=default; //动态链接析构函数
private:
string bookNo; //这本书的isbn号
protected:
double price=0.0; //不打折的价格
};
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)
{cout<<"Bulk_quote construct function"<<endl;}
//重写虚函数
double net_price(size_t n) const override {cout<<"double net_price(size_t)"<<endl; return n*price;}
//再次说明,请声明函数后一定要记得定义它,不然我这是出了各种莫名其妙的错误!
// ~Bulk_quote2(){cout<<"~Bulk_quote2()"<<endl;}
///--------------------------------
pair<size_t, double> discount_policy() const {return {min_qty, discount};}
private:
size_t min_qty=0;
double discount=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) {cout<<"Disc_quote构造函数"<<endl;}
double net_price(size_t) const = 0; //纯虚函数
///-------------------------------------------------
pair<size_t, double> discount_policy() const {return {quantity, discount};}
protected:
size_t quantity=0;
double discount=0.0;
};
void fun1()
{
Bulk_quote bulk;
Bulk_quote *bulkP=&bulk;
Quote *itemP=&bulk;
bulkP->discount_policy(); //好的这是一个指针类似(*bulkP).discount_policy()
// item->discount_policy(); error:Quote里面没有这个成员
}
/**
Name Collisions and Inheritance(名字冲突的时候继承)
*/
struct Base
{
Base():mem(0) {}
protected:
int mem;
};
struct Derived : Base
{
Derived(int i) : mem(i) {} //这里初始化的是Derived的mem用i,而Base::mem是默认初始化的
int get_mem() { return mem; } //返回Derived::mem
protected:
int mem; //吧base的mem隐藏起来
};
void fun2()
{
Derived d(42);
cout<<d.get_mem()<<endl; //输出42
}
/**
使用作用域操作符使用隐藏的成员
*/
/*
除了重写继承的虚函数的派生类,通常
不应使用基类中定义的名字。
*/
/**
As Usual, Name Lookup Happens before Type Checking
*/
struct Base2
{
Base2():mem(0) {}
int memfcn() {}
protected:
int mem;
};
struct Derived2 : Base2
{
Derived2()=default;
Derived2(int i) : mem(i) {} //这里初始化的是Derived的mem用i,而Base::mem是默认初始化的
int get_mem() { return mem; } //返回Derived::mem
int memfcn(int) {} //吧Base2中的memfcn隐藏了
protected:
int mem; //吧base的mem隐藏起来
};
void fun3()
{
Derived2 d;
Base2 b;
b.memfcn(); //----->Base的Base::memfcn()
d.memfcn(10); //----->Derived的Derived::memfcn()
// d.memfcn(); error:这个Derived里面继承Base里面的memfcn被隐藏了
d.Base2::memfcn(); //ok:调用Base::memfcn
}
/**
Virtual Functions and Scope
*/
class Base3
{
public:
virtual int fcn() {cout<<"Base3--->virtual int fcn()"<<endl;}
};
class D1 : public Base3
{
public:
int fcn(int){cout<<"D1--->int fcn(int)"<<endl;} //这个是隐藏了fcn不叫override
virtual void f2(){cout<<"D1--->virtual void f2()"<<endl;}
};
class D2 : public D1
{
public:
int fcn(int){cout<<"D2--->int fcn(int)"<<endl;} //这个是隐藏,没有override在D1这个不是虚函数
int fcn(){cout<<"D2--->int fcn()"<<endl;} //是覆盖,override
void f2(){cout<<"D2--->void f2()"<<endl;} //覆盖,virtual f2 from D1
};
void fun4()
{
Base3 b3obj; D1 d1obj; D2 d2obj;
Base3 *b3p1=&b3obj, *b3p2=&d1obj, *b3p3=&d2obj;
b3p1->fcn(); //这个调用了Base3::fcn
b3p2->fcn(); //调用Base3::fcn
b3p3->fcn(); //调用D2::fcn
D1 *d1p=&d1obj; D2 *d2p=&d2obj;
// b3p2->f2(); error:Base没有f2!!注意是Base而不是D1,因为*b3p2的类型是Base多余部分没有拷贝
d1p->f2(); //D1--->virtual void f2()
d2p->f2(); //D2--->void f2()
Base3 *p1=&d2obj; D1 *p2=&d2obj; D2 *p3=&d2obj;
// p1->fcn(42); error:Base3没有fcn(int)函数
p2->fcn(42); //D1--->int fcn(int)
p3->fcn(42); //D2--->int fcn(int)
}
/**************************************
构造函数和拷贝控制
**************************************/
/**
Virtual Destructors(虚析构函数)
*/
void fun5()
{
Quote *itemP=new Quote;
delete itemP;
itemP=new Bulk_quote;
delete itemP;
}
/**************************************
15.7.2. Synthesized Copy Control and Inheritance
**************************************/
/**
Base Classes and Deleted Copy Control in the Derived
*/
class B
{
public:
B(){cout<<"B()构造函数"<<endl;}
B(const B&)=delete; //这个函数的意思是,这个类不能调用这个函数,默认的都不行
};
class D : public B
{
//什么都没有!!!
};
void fun6()
{
D d;
// D d2(d); error:这个会默认调用了B的B(const B&)但是这个是delete了的
// D d3(std::move(d)); error:同上
}
/**
Move Operations and Inheritance(移动操作与继承)
*/
/*
哎!大家一定要学好英语啊,我是以前不能长期坚持搞得现在英语真是“阴雨”
用的翻译软件,╮(╯▽╰)╭翻译的什么玩意,有的我自己都看不懂,读不通
*/
class Quote2
{
public:
Quote2()=default; //默认构造函数
Quote2(const string &book, double sales_price):bookNo(book), price(sales_price)
{cout<<"Quote gouzhao function"<<endl;}
//拷贝函数
Quote2(const Quote2&)=default;
Quote2(Quote2&&)=default;
//拷贝赋值运算符,和移动赋值运算符
Quote2& operator=(const Quote2&)=default;
Quote2& operator=(Quote2&&)=default;
//析构函数
virtual ~Quote2()=default; //动态链接析构函数
string isbn() const {return bookNo;}
//返回指定数量的项目总销售价格
//派生类将重写应用不同的折扣算法
virtual double net_price(size_t n) const {return n*price;}
private:
string bookNo; //这本书的isbn号
protected:
double price=0.0; //不打折的价格
};
/**************************************
15.7.3. Derived-Class Copy-Control Members
派生类拷贝控制成员
**************************************/
/*
当派生类定义了一个复制或移动操作,那么这个操作符将负责整个类的相应操作
还包括基类的成员的相应操作
*/
/**
定义一个派生拷贝或移动构造函数
*/
/*
默认情况下,基类的默认构造函数初始化基类部分
派生的对象。如果我们想要复制(或移动)基类部分,我们必须
显式使用复制(或移动)在对基类构造函数
派生的构造函数初始化列表。
*/
/*
这里我就不给大家定义了,书上给的很泛,没什么意义
*/
class Base { /* ... */ } ;
class D: public Base {
public:
// by default, the base class default constructor initializes the base part of an object
// to use the copy or move constructor, we must explicitly call that
// constructor in the constructor initializer list
D(const D& d): Base(d) // copy the base members
{ /* ... */ }//initializers for members of D
D(D&& d): Base(std::move(d)) // move the base members
/* initializers for members of D / { /* ... */ }
};
// Base::operator=(const Base&) is not invoked automatically
D &D::operator=(const D &rhs)
{
Base::operator=(rhs); // assigns the base part
// assign the members in the derived class, as usual,
// handling self-assignment and freeing existing resources as appropriate
return *this;
}
class D: public Base {
public:
// Base::~Base invoked automatically
~D() { /* do what it takes to clean up derived members / }
};
析构基类会自动进行!!!但是{}里面的清理对象还是都要写,基类已经写delete了的就
会自动调用基类析构函数时调用!!
*/
/**************************************
15.7.4.继承析构函数
**************************************/
/*
在新标准下,一个派生类可以调用基类的构造函数
*/
class Bulk_quote2 : public Disc_quote
{
public:
using Disc_quote::Disc_quote;
//构造函数等价于
/*
Bulk_quote(const string & book, double price, size_t qty, double disc)
: Disc_quote(book, price, qty, disc){}
*/
double net_price(size_t n) const {cout<<"Bulk_quote2,net_price"<<endl; return n*price;}
};
/**
继承构造函数的特点
*/
/*
好吧书上一堆“阴雨”!!!
*/
int main()
{
cout<<">>------------------------------fun1-----------------------------------<<"<<endl;
cout<<">>------------------------------fun2-----------------------------------<<"<<endl;
fun2();
cout<<">>------------------------------fun3-----------------------------------<<"<<endl;
cout<<">>------------------------------fun4-----------------------------------<<"<<endl;
fun4();
cout<<">>------------------------------fun5-----------------------------------<<"<<endl;
fun5();
cout<<">>------------------------------fun6-----------------------------------<<"<<endl;
fun6();
system("pause");
return 0;
}
void fun5() { Quote *itemP=new Quote; delete itemP; itemP=new Bulk_quote; delete itemP; }
15.7.2. Synthesized Copy Control and Inheritance
class B { public: B(){cout<<"B()构造函数"<<endl;} B(const B&)=delete; //这个函数的意思是,这个类不能调用这个函数,默认的都不行 }; class D : public B { //什么都没有!!! }; void fun6() { D d; // D d2(d); error:这个会默认调用了B的B(const B&)但是这个是delete了的 // D d3(std::move(d)); error:同上 }
Move Operations and Inheritance(移动操作与继承)
用的翻译软件,╮(╯▽╰)╭翻译的什么玩意,有的我自己都看不懂,读不通
class Quote2 { public: Quote2()=default; //默认构造函数 Quote2(const string &book, double sales_price):bookNo(book), price(sales_price) {cout<<"Quote gouzhao function"<<endl;} //拷贝函数 Quote2(const Quote2&)=default; Quote2(Quote2&&)=default; //拷贝赋值运算符,和移动赋值运算符 Quote2& operator=(const Quote2&)=default; Quote2& operator=(Quote2&&)=default; //析构函数 virtual ~Quote2()=default; //动态链接析构函数 string isbn() const {return bookNo;} //返回指定数量的项目总销售价格 //派生类将重写应用不同的折扣算法 virtual double net_price(size_t n) const {return n*price;} private: string bookNo; //这本书的isbn号 protected: double price=0.0; //不打折的价格 };
15.7.3. Derived-Class Copy-Control Members
派生类拷贝控制成员
还包括基类的成员的相应操作
派生的对象。如果我们想要复制(或移动)基类部分,我们必须
显式使用复制(或移动)在对基类构造函数
派生的构造函数初始化列表。
class Base { /* ... */ } ; class D: public Base { public: // by default, the base class default constructor initializes the base part of an object // to use the copy or move constructor, we must explicitly call that // constructor in the constructor initializer list D(const D& d): Base(d) // copy the base members { /* ... */ }//initializers for members of D D(D&& d): Base(std::move(d)) // move the base members /* initializers for members of D / { /* ... */ } }; // Base::operator=(const Base&) is not invoked automatically D &D::operator=(const D &rhs) { Base::operator=(rhs); // assigns the base part // assign the members in the derived class, as usual, // handling self-assignment and freeing existing resources as appropriate return *this; } class D: public Base { public: // Base::~Base invoked automatically ~D() { /* do what it takes to clean up derived members / } };
析构基类会自动进行!!!但是{}里面的清理对象还是都要写,基类已经写delete了的就
class Bulk_quote2 : public Disc_quote { public: using Disc_quote::Disc_quote; //构造函数等价于 /* Bulk_quote(const string & book, double price, size_t qty, double disc) : Disc_quote(book, price, qty, disc){} */ double net_price(size_t n) const {cout<<"Bulk_quote2,net_price"<<endl; return n*price;} };
继承构造函数的特点
/** * 功能:继承类的范围,构造函数和拷贝控制 * 时间:2014年7月22日07:53:20 * 作者:cutter_point */ #include<iostream> #include<algorithm> using namespace std; /* 当用派生类执行函数的时候,首先会在当前的类里面找 如果找不到就一级一级地往上找。 */ /** Name Lookup Happens at Compile Time */ class Quote { public: Quote()=default; Quote(const string &book, double sales_price):bookNo(book), price(sales_price) {cout<<"Quote gouzhao function"<<endl;} string isbn() const {return bookNo;} //返回指定数量的项目总销售价格 //派生类将重写应用不同的折扣算法 virtual double net_price(size_t n) const {return n*price;} virtual ~Quote()=default; //动态链接析构函数 private: string bookNo; //这本书的isbn号 protected: double price=0.0; //不打折的价格 }; 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) {cout<<"Bulk_quote construct function"<<endl;} //重写虚函数 double net_price(size_t n) const override {cout<<"double net_price(size_t)"<<endl; return n*price;} //再次说明,请声明函数后一定要记得定义它,不然我这是出了各种莫名其妙的错误! // ~Bulk_quote2(){cout<<"~Bulk_quote2()"<<endl;} ///-------------------------------- pair<size_t, double> discount_policy() const {return {min_qty, discount};} private: size_t min_qty=0; double discount=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) {cout<<"Disc_quote构造函数"<<endl;} double net_price(size_t) const = 0; //纯虚函数 ///------------------------------------------------- pair<size_t, double> discount_policy() const {return {quantity, discount};} protected: size_t quantity=0; double discount=0.0; }; void fun1() { Bulk_quote bulk; Bulk_quote *bulkP=&bulk; Quote *itemP=&bulk; bulkP->discount_policy(); //好的这是一个指针类似(*bulkP).discount_policy() // item->discount_policy(); error:Quote里面没有这个成员 } /** Name Collisions and Inheritance(名字冲突的时候继承) */ struct Base { Base():mem(0) {} protected: int mem; }; struct Derived : Base { Derived(int i) : mem(i) {} //这里初始化的是Derived的mem用i,而Base::mem是默认初始化的 int get_mem() { return mem; } //返回Derived::mem protected: int mem; //吧base的mem隐藏起来 }; void fun2() { Derived d(42); cout<<d.get_mem()<<endl; //输出42 } /** 使用作用域操作符使用隐藏的成员 */ /* 除了重写继承的虚函数的派生类,通常 不应使用基类中定义的名字。 */ /** As Usual, Name Lookup Happens before Type Checking */ struct Base2 { Base2():mem(0) {} int memfcn() {} protected: int mem; }; struct Derived2 : Base2 { Derived2()=default; Derived2(int i) : mem(i) {} //这里初始化的是Derived的mem用i,而Base::mem是默认初始化的 int get_mem() { return mem; } //返回Derived::mem int memfcn(int) {} //吧Base2中的memfcn隐藏了 protected: int mem; //吧base的mem隐藏起来 }; void fun3() { Derived2 d; Base2 b; b.memfcn(); //----->Base的Base::memfcn() d.memfcn(10); //----->Derived的Derived::memfcn() // d.memfcn(); error:这个Derived里面继承Base里面的memfcn被隐藏了 d.Base2::memfcn(); //ok:调用Base::memfcn } /** Virtual Functions and Scope */ class Base3 { public: virtual int fcn() {cout<<"Base3--->virtual int fcn()"<<endl;} }; class D1 : public Base3 { public: int fcn(int){cout<<"D1--->int fcn(int)"<<endl;} //这个是隐藏了fcn不叫override virtual void f2(){cout<<"D1--->virtual void f2()"<<endl;} }; class D2 : public D1 { public: int fcn(int){cout<<"D2--->int fcn(int)"<<endl;} //这个是隐藏,没有override在D1这个不是虚函数 int fcn(){cout<<"D2--->int fcn()"<<endl;} //是覆盖,override void f2(){cout<<"D2--->void f2()"<<endl;} //覆盖,virtual f2 from D1 }; void fun4() { Base3 b3obj; D1 d1obj; D2 d2obj; Base3 *b3p1=&b3obj, *b3p2=&d1obj, *b3p3=&d2obj; b3p1->fcn(); //这个调用了Base3::fcn b3p2->fcn(); //调用Base3::fcn b3p3->fcn(); //调用D2::fcn D1 *d1p=&d1obj; D2 *d2p=&d2obj; // b3p2->f2(); error:Base没有f2!!注意是Base而不是D1,因为*b3p2的类型是Base多余部分没有拷贝 d1p->f2(); //D1--->virtual void f2() d2p->f2(); //D2--->void f2() Base3 *p1=&d2obj; D1 *p2=&d2obj; D2 *p3=&d2obj; // p1->fcn(42); error:Base3没有fcn(int)函数 p2->fcn(42); //D1--->int fcn(int) p3->fcn(42); //D2--->int fcn(int) } /************************************** 构造函数和拷贝控制 **************************************/ /** Virtual Destructors(虚析构函数) */ void fun5() { Quote *itemP=new Quote; delete itemP; itemP=new Bulk_quote; delete itemP; } /************************************** 15.7.2. Synthesized Copy Control and Inheritance **************************************/ /** Base Classes and Deleted Copy Control in the Derived */ class B { public: B(){cout<<"B()构造函数"<<endl;} B(const B&)=delete; //这个函数的意思是,这个类不能调用这个函数,默认的都不行 }; class D : public B { //什么都没有!!! }; void fun6() { D d; // D d2(d); error:这个会默认调用了B的B(const B&)但是这个是delete了的 // D d3(std::move(d)); error:同上 } /** Move Operations and Inheritance(移动操作与继承) */ /* 哎!大家一定要学好英语啊,我是以前不能长期坚持搞得现在英语真是“阴雨” 用的翻译软件,╮(╯▽╰)╭翻译的什么玩意,有的我自己都看不懂,读不通 */ class Quote2 { public: Quote2()=default; //默认构造函数 Quote2(const string &book, double sales_price):bookNo(book), price(sales_price) {cout<<"Quote gouzhao function"<<endl;} //拷贝函数 Quote2(const Quote2&)=default; Quote2(Quote2&&)=default; //拷贝赋值运算符,和移动赋值运算符 Quote2& operator=(const Quote2&)=default; Quote2& operator=(Quote2&&)=default; //析构函数 virtual ~Quote2()=default; //动态链接析构函数 string isbn() const {return bookNo;} //返回指定数量的项目总销售价格 //派生类将重写应用不同的折扣算法 virtual double net_price(size_t n) const {return n*price;} private: string bookNo; //这本书的isbn号 protected: double price=0.0; //不打折的价格 }; /************************************** 15.7.3. Derived-Class Copy-Control Members 派生类拷贝控制成员 **************************************/ /* 当派生类定义了一个复制或移动操作,那么这个操作符将负责整个类的相应操作 还包括基类的成员的相应操作 */ /** 定义一个派生拷贝或移动构造函数 */ /* 默认情况下,基类的默认构造函数初始化基类部分 派生的对象。如果我们想要复制(或移动)基类部分,我们必须 显式使用复制(或移动)在对基类构造函数 派生的构造函数初始化列表。 */ /* 这里我就不给大家定义了,书上给的很泛,没什么意义 */ class Base { /* ... */ } ; class D: public Base { public: // by default, the base class default constructor initializes the base part of an object // to use the copy or move constructor, we must explicitly call that // constructor in the constructor initializer list D(const D& d): Base(d) // copy the base members { /* ... */ }//initializers for members of D D(D&& d): Base(std::move(d)) // move the base members /* initializers for members of D / { /* ... */ } }; // Base::operator=(const Base&) is not invoked automatically D &D::operator=(const D &rhs) { Base::operator=(rhs); // assigns the base part // assign the members in the derived class, as usual, // handling self-assignment and freeing existing resources as appropriate return *this; } class D: public Base { public: // Base::~Base invoked automatically ~D() { /* do what it takes to clean up derived members / } }; 析构基类会自动进行!!!但是{}里面的清理对象还是都要写,基类已经写delete了的就 会自动调用基类析构函数时调用!! */ /************************************** 15.7.4.继承析构函数 **************************************/ /* 在新标准下,一个派生类可以调用基类的构造函数 */ class Bulk_quote2 : public Disc_quote { public: using Disc_quote::Disc_quote; //构造函数等价于 /* Bulk_quote(const string & book, double price, size_t qty, double disc) : Disc_quote(book, price, qty, disc){} */ double net_price(size_t n) const {cout<<"Bulk_quote2,net_price"<<endl; return n*price;} }; /** 继承构造函数的特点 */ /* 好吧书上一堆“阴雨”!!! */ int main() { cout<<">>------------------------------fun1-----------------------------------<<"<<endl; cout<<">>------------------------------fun2-----------------------------------<<"<<endl; fun2(); cout<<">>------------------------------fun3-----------------------------------<<"<<endl; cout<<">>------------------------------fun4-----------------------------------<<"<<endl; fun4(); cout<<">>------------------------------fun5-----------------------------------<<"<<endl; fun5(); cout<<">>------------------------------fun6-----------------------------------<<"<<endl; fun6(); system("pause"); return 0; }
茶,冷了,苦涩了。喝茶果然还是热点好,香味十足,甘甜完美。冷淡下来了,就只有火热的回忆,和苦涩的冰凉!
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。