继承类的范围,构造函数和拷贝控制
当用派生类执行函数的时候,首先会在当前的类里面找
如果找不到就一级一级地往上找。
如果找不到就一级一级地往上找。
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)
}
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;}
};
继承构造函数的特点
好吧书上一堆“阴雨”!!!~~~~
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;
}
茶,冷了,苦涩了。喝茶果然还是热点好,香味十足,甘甜完美。冷淡下来了,就只有火热的回忆,和苦涩的冰凉!