#include
#include
using namespace std;
using std::string;
class Item_base {
public:
Item_base(const std::string &book = "",
double sales_price = 0.0):
isbn(book), price(sales_price) { }
std::string book() const { return isbn; }
//为了指明函数为虚函数,在其返回类型前面加上保留字virtual,除了构造函数之外,任意非static成员函数都可以是虚函数,保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。
virtual double net_price(std::size_t n) const
{ return n * price; }
virtual ~Item_base() { }
private:
std::string isbn;
protected:
double price;
};
class Bulk_item : public Item_base {
public:
double net_price(std::size_t) const;
void memfcn(const Bulk_item &d, const Item_base &b);
private:
std::size_t min_qty;
double discount;
};
//下面如果为 “virtual double Bulk_item::net_price(size_t cnt) const “,会报:"virtual outside class declaration" 错误,验证了:保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上
double Bulk_item::net_price(size_t cnt) const
{
if(cnt >= min_qty)
return cnt * (1 - discount) * price;
else
return cnt * price;
}
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
{
double ret = price;
ret = d.price;
//ret = b.price; 报错:‘double Item_base::price’ is protected‘ ,说明派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限
}
#include
#include
using namespace std;
using std::string;
class Item_base {
public:
Item_base(const std::string &book = "",
double sales_price = 0.0):
isbn(book), price(sales_price) { }
std::string book() const { return isbn; }
//为了指明函数为虚函数,在其返回类型前面加上保留字virtual,除了构造函数之外,任意非static成员函数都可以是虚函数,保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。
virtual double net_price(std::size_t n) const
{
cout << "------Item_base::net_price call------" << endl;
return n * price;
}
virtual ~Item_base() { }
private:
std::string isbn;
protected:
double price;
};
class Bulk_item : public Item_base {
public:
double net_price(std::size_t) const;
void memfcn(const Bulk_item &d, const Item_base &b);
private:
std::size_t min_qty;
double discount;
};
//下面如果为 “virtual double Bulk_item::net_price(size_t cnt) const “,会报:"virtual outside class declaration" 错误,验证了:保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上
double Bulk_item::net_price(size_t cnt) const
{
cout << "------Bulk_item::net_price call------" << endl;
if(cnt >= min_qty)
return cnt * (1 - discount) * price;
else
return cnt * price;
}
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
{
double ret = price;
ret = d.price;
//ret = b.price; 报错:‘double Item_base::price’ is protected‘ ,说明派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限
}
void print_total(ostream &os,
const Item_base &item, size_t n)
{
os << "ISBN: " << item.book()
<< "\tnumber sold: " << n << "\ttotal price: "
<< item.net_price(n) << endl;
}
int main()
{
//测试代码,可以在运行时确定virtual函数调用
Item_base base;
Bulk_item derived;
print_total(cout,base,10);
cout << "-------------------------" << endl;
print_total(cout,derived,10);
return 0;
}
输出:
pateo@pateo-B86N53X:~/work/study$ g++ main.cc -o main
pateo@pateo-B86N53X:~/work/study$ ./main
------Item_base::net_price call------
ISBN: number sold: 10 total price: 0
-------------------------
------Bulk_item::net_price call------
ISBN: number sold: 10 total price: 0
pateo@pateo-B86N53X:~/work/study$
#include
#include
using namespace std;
using std::string;
class Item_base {
public:
Item_base(const std::string &book = " ",
double sales_price = 0.0):
isbn(book), price(sales_price) { }
std::string book() const {
return "Item_base::book";
}
//为了指明函数为虚函数,在其返回类型前面加上保留字virtual,除了构造函数之外,任意非static成员函数都可以是虚函数,保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。
virtual double net_price(std::size_t n) const
{
cout << "------Item_base::net_price call------" << endl;
return n * price;
}
virtual ~Item_base() { }
private:
std::string isbn;
protected:
double price;
};
class Bulk_item : public Item_base {
public:
double net_price(std::size_t) const;
void memfcn(const Bulk_item &d, const Item_base &b);
std::string book() const {
return "Bulk_item::book";
}
private:
std::size_t min_qty;
double discount;
};
//下面如果为 “virtual double Bulk_item::net_price(size_t cnt) const “,会报:"virtual outside class declaration" 错误,验证了:保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上
double Bulk_item::net_price(size_t cnt) const
{
cout << "------Bulk_item::net_price call------" << endl;
if(cnt >= min_qty)
return cnt * (1 - discount) * price;
else
return cnt * price;
}
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
{
double ret = price;
ret = d.price;
//ret = b.price; 报错:‘double Item_base::price’ is protected‘ ,说明派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限
}
void print_total(ostream &os,
const Item_base &item, size_t n)
{
os << "ISBN: " << item.book()
<< "\tnumber sold: " << n << "\ttotal price: "
<< item.net_price(n) << endl;
}
int main()
{
//测试代码,在编译时确定非virtual函数调用
Item_base base;
Bulk_item derived;
print_total(cout,base,10);
cout << "-------------------------" << endl;
print_total(cout,derived,10);
return 0;
}
输出:
pateo@pateo-B86N53X:~/work/study$ g++ main.cc -o main
pateo@pateo-B86N53X:~/work/study$ ./main
------Item_base::net_price call------
ISBN: Item_base::book number sold: 10 total price: 0
-------------------------
------Bulk_item::net_price call------
ISBN: Item_base::book number sold: 10 total price: 0
pateo@pateo-B86N53X:~/work/study$
pateo@pateo-B86N53X:~/work/study$
#include
#include
using namespace std;
using std::string;
class Item_base {
public:
Item_base(const std::string &book = " ",
double sales_price = 0.0):
isbn(book), price(sales_price) { }
std::string book() const {
return "Item_base::book";
}
//为了指明函数为虚函数,在其返回类型前面加上保留字virtual,除了构造函数之外,任意非static成员函数都可以是虚函数,保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。
virtual double net_price(std::size_t n) const
{
cout << "------Item_base::net_price call------" << endl;
return n * price;
}
virtual ~Item_base() { }
private:
std::string isbn;
protected:
double price;
};
class Bulk_item : public Item_base {
public:
double net_price(std::size_t) const;
void memfcn(const Bulk_item &d, const Item_base &b);
std::string book() const {
return "Bulk_item::book";
}
private:
std::size_t min_qty;
double discount;
};
//下面如果为 “virtual double Bulk_item::net_price(size_t cnt) const “,会报:"virtual outside class declaration" 错误,验证了:保留字virtual只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上
double Bulk_item::net_price(size_t cnt) const
{
cout << "------Bulk_item::net_price call------" << endl;
if(cnt >= min_qty)
return cnt * (1 - discount) * price;
else
return cnt * price;
}
void Bulk_item::memfcn(const Bulk_item &d, const Item_base &b)
{
double ret = price;
ret = d.price;
//ret = b.price; 报错:‘double Item_base::price’ is protected‘ ,说明派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限
}
void print_total(ostream &os,
const Item_base &item, size_t n)
{
os << "ISBN: " << item.book()
<< "\tnumber sold: " << n << "\ttotal price: "
<< item.net_price(n) << endl;
}
int main()
{
//测试代码,覆盖虚函数机制
Bulk_item derived;
Item_base *baseP = &derived;
double d = baseP->Item_base::net_price(42);
return 0;
}
输出:
pateo@pateo-B86N53X:~/work/study$ g++ main.cc -o main
pateo@pateo-B86N53X:~/work/study$ ./main
------Item_base::net_price call------
pateo@pateo-B86N53X:~/work/study$
如下公共、私有和保护的继承
#include
#include
using namespace std;
using std::string;
class Base{
public :
void basemem();
protected :
int i;
};
struct Public_derived : public Base
{
int use_base(){return i;}
};
struct Private_derived : private Base
{
int use_base(){return i;}
};
int main()
{
Base b;
Public_derived d1;
Private_derived d2;
b.basemem();//ok
d1.basemem();//ok
d2.basemem();//error
return 0;
}
输出:
pateo@pateo-B86N53X:~/work/study$ g++ main.cc -o main
main.cc: In function ‘int main()’:
main.cc:8: error: ‘void Base::basemem()’ is inaccessible
main.cc:32: error: within this context
main.cc:32: error: ‘Base’ is not an accessible base of ‘Private_derived’
pateo@pateo-B86N53X:~/work/study$
#include
#include
using namespace std;
using std::string;
class Base{
public :
void basemem();
protected :
int i;
};
struct Public_derived : public Base
{
int use_base(){return i;}
};
struct Private_derived : private Base
{
int use_base(){return i;}
};
struct Derived_from_Public : public Public_derived
{
int use_base(){return i;}
};
int main()
{
Derived_from_Public d3;
d3.basemem();//ok
return 0;
}
说明:
派生方式 基类的public成员 基类的protected成员 基类的private成员 派生方式引起的访问属性变化概括
private派生 变为private成员 变为private成员 不可见 基类中的非私有成员都成为派生类中的私有成员
protected派生 变为protected成员 变为private成员 不可见 基类中的非私有成员在派生类中的访问属性都降一级
public派生 仍为public成员 仍为protected成员 不可见 基类中的非私有成员在派生类中的访问属性保持不变
如果进行private或protected继承,则基类成员的访问级别在派生类中比在基类中更受限
#include
#include
using namespace std;
using std::string;
class Base{
public :
int basemem(){return i;}
protected :
int i;
};
class Private_derived : private Base
{
public:
using Base::basemem;//使用using声明访问基类中成员
protected :
using Base::i;//使用using声明访问基类中成员
};
int main()
{
Private_derived d1;
d1.basemem();//ok
return 0;
}
比较下面
#include
#include
using namespace std;
using std::string;
class Base{
public :
int basemem(){return i;}
protected :
int i;
};
class Private_derived : private Base
{
};
int main()
{
Private_derived d1;
d1.basemem();//error
return 0;
}
使用class关键字来定义类,那么定义在第一个访问标号前的任何成员都隐式制定为private;如果使用struct关键字,那么这些成员都是public。使用class还是struct关键字来定义类,仅仅影响默认的初始化访问级别。同样,使用class保留字定义的派生类默认具有private继承,而用struct保留字定义的类默认具有public继承,如下
#include
#include
using namespace std;
using std::string;
class Base{
public :
int basemem(){return i;}
protected :
int i;
};
class Private_derived : Base
{
};
int main()
{
Private_derived d1;
d1.basemem();//error
return 0;
}
对比下面
#include
#include
using namespace std;
using std::string;
class Base{
public :
int basemem(){return i;}
protected :
int i;
};
struct Private_derived : Base
{
};
int main()
{
Private_derived d1;
d1.basemem();//ok
return 0;
}