C++中的public、private、protected成员继承问题
我是C++菜鸟,刚学了一点C++。
先看例子1:
/* Item.h */
#include <iostream>
#include <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;}
bool
isPrecious(Item_base
&other);
virtual
double
net_price(std::size_t
n)
const
{
return
n*price;
}
virtual
~Item_base()
{}
private:
std::string
isbn;
double
price;
};
/* Item.cc */
#include "Item.h"
bool
Item_base::isPrecious(Item_base
&other)
{
if(price
>
other.price)
return
true;
return
false;
}
/* test.cc */
#include "Item.h"
using
std::cout;
using
std::endl;
int
main()
{
Item_base
base("TN-119",12.3);
cout
<<"isbn: "
<<base.book()
<<endl;
double
total_price
=
base.net_price(3);
cout
<<"total: "
<<total_price
<<endl;
Item_base
base1("TN-120",15.4);
if(base.isPrecious(base1))
cout
<<base.book()
<<" is precious than "
<<base1.book()
<<endl;
else
cout
<<base.book()
<<" is cheaper than "
<<base1.book()
<<endl;
return
0;
}
在没有继承的情况下,只要public、private就足够了,private成员不能被用户(test.cc)使用,用户只能通过类的public接口来使用它们,比如用base.book()来获得base.isbn。
在类中,该类(不是该类的一个对象,而是该类的任何对象)的private成员都可以被访问,如bool Item_base::isPrecious(Item_base &other)函数中,就可以访问Item_base类的price成员,当然成员的访问要依赖于具体的对象,如这里的this、other。
:
/* Item.h */
#include <iostream>
#include <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;}
bool
isPrecious(Item_base
&other);
virtual
double
net_price(std::size_t
n)
const
{
return
n*price;
}
virtual
~Item_base()
{}
private:
std::string
isbn;
double
price;
};
class
Bulk_item
:
public
Item_base
{
public:
Bulk_item(std::size_t
min,
double
disc_rate)
:
min_qty(min),
discount(disc_rate)
{}
Bulk_item(const
std::string
&book,
double
sales_price,
std::size_t
min,
double
dis)
:
Item_base(book,sales_price),
min_qty(min),
discount(dis)
{}
private:
std::size_t
min_qty;
double
discount;
};
/* Item.cc */
#include "Item.h"
bool
Item_base::isPrecious(Item_base
&other)
{
if(price
>
other.price)
return
true;
return
false;
}
/* test.cc */
#include "Item.h"
using
std::cout;
using
std::endl;
int
main()
{
Item_base
base("TN-119",12.3);
Bulk_item
bulk("TNP-132",13.3,3,0.2);
if(base.isPrecious(bulk))
cout
<<base.book()
<<" is more expensive than "
<<bulk.book()
<<endl;
if(bulk.isPrecious(base)) //ok! isPrecious is base's func, it can access base's data
cout
<<base.book()
<<" is cheaper than "
<<bulk.book()
<<endl;
return
0;
}
Bulk_item类继承了Item_base类,并从哪里继承了bool
isPrecious(Item_base
&other)方法,但要注意该方法仍然是基类定义的,只是被子类继承过来用而已。再看test.cc中的base.isPrecious(bulk)调用,该实参被自动转化为Item_base类,isPrecious()函数仍可以访问bulk从基类那继承来的private成员price。
最后看一下例子3:
/* Item.h */
#include <iostream>
#include <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;}
bool
isPrecious(Item_base
&other);
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:
Bulk_item(std::size_t
min,
double
disc_rate)
:
min_qty(min),
discount(disc_rate)
{}
Bulk_item(const
std::string
&book,
double
sales_price,
std::size_t
min,
double
dis)
:
Item_base(book,sales_price),
min_qty(min),
discount(dis)
{}
double
net_price(std::size_t
n)
const;
private:
std::size_t
min_qty;
double
discount;
};
/* Item.cc */
#include "Item.h"
bool
Item_base::isPrecious(Item_base
&other)
{
if(price
>
other.price)
return
true;
return
false;
}
double
Bulk_item::net_price(std::size_t
n)
const
{
if(n>=min_qty)
return
price*(1-discount)*n;
return
price*n;
}
/* test.cc */
#include "Item.h"
using
std::cout;
using
std::endl;
int
main()
{
Item_base
base("TN-119",12.3);
Bulk_item
bulk("TNP-132",13.3,3,0.2);
cout
<<base.book()
<<" 3X total: "
<<base.net_price(3)
<<endl;
cout
<<bulk.book()
<<" 3X total: "
<<bulk.net_price(3)
<<endl;
return
0;
}
和前面最大的不同在于,子类要重写基类的某个方法,如这里的double
Bulk_item::net_price(std::size_t
n)
const。那么这个方法就完全是子类自己定义的,它将不能访问从基类那继承过来的private成员,除非在基类中把这些成员定义为protected。
和例子1中讲的一样,在类中访问有权限访问的成员时,必须依赖于该类的一个对象,如这里的this(隐式的);同样,若net_price(xx, Bulk_item bulk)还有一个bulk参数,那么它也可以访问bulk.price;但是,若net_price(xx, Item_base base)有一个base参数,那它不能访问base.price,因为一个类内不能访问其它类的非public成员。
C++中的public、private、protected成员继承问题的更多相关文章
- [转]java中作用域public private protected 以及不写的区别
在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes,认为都是自己的朋友 ...
- Java中public,private,protected,和默认的区别
Java中public,private,protected,和默认的区别 1.private修饰词,表示成员是私有的,只有自身可以访问: 2.protected,表示受保护权限,体现在继承,即子类可以 ...
- php class中public,private,protected的区别,以及实例
一,public,private,protected的区别 public:权限是最大的,可以内部调用,实例调用等. protected: 受保护类型,用于本类和继承类调用. private: 私有类型 ...
- 访问权限系列一(public/private/protected/default):成员变量
通过两个程序包对自身或互相之间的访问,得到结果.(先编译Test_01,得到class文件,通过Test的集中访问情况) 如下Test.java中内容: package com.java; /* * ...
- PHP中const,static,public,private,protected的区别
原文地址:http://small.aiweimeng.top/index.php/archives/54.html const: 定义常量,一般定义后不可改变static: 静态,类名可以访问pub ...
- PHP中public,private,protected,abstract等关键字用法详解
PHP中常用的关键字 在PHP中包含了很多对函数和类进行限制的关键字,常用的通常有abstract,final,interface,public,protected,private,static等等, ...
- public/private/protected访问控制权限的区别
//public/private/protected访问控制权限的区别//时间:2016/8/16 //(一)修饰成员: //public: 在类内.类外都能使用 . //protected: 在类内 ...
- 深入浅出OOP(五): C#访问修饰符(Public/Private/Protected/Internal/Sealed/Constants)
访问修饰符(或者叫访问控制符)是面向对象语言的特性之一,用于对类.类成员函数.类成员变量进行访问控制.同时,访问控制符也是语法保留关键字,用于封装组件. Public, Private, Protec ...
- public private protected和默认的区别(转自百度)
public private protected和默认的区别 Java中对类以及类中的成员变量和成员方法通过访问控制符(access specifier)进行区分控制.刚学Java语言的同学可能对pu ...
- 【转】C++ 类访问控制public/private/protected探讨
示例1:---------------------------------------- class C{ int c1; int c2;public: void set(C* s, int i, i ...
随机推荐
- GUC-10 线程八锁
/* * 题目:判断打印的 "one" or "two" ? * * 1. 两个普通同步方法,两个线程,标准打印, 打印? //one two * 2. 新增 ...
- django Form 表单 总结与小实例
开头寄语: 这几天一直在看Django的form表单验证,然后想对于这几天要有个总结. 首先,先来看一下找到的一个form表单验证的流程: 验证过程 流程详解1. 函数full_clean()依次调用 ...
- Code First 数据库迁移
当 Entity Framework Code First 的数据模型发生改变时,默认会引发一个System.InvalidOperationException 的异常.解决方法是使用DropCrea ...
- C#使用Pechkin与CPechkin生成PDF
http://blog.sina.com.cn/s/blog_5a52cec70102wpcf.html 1. Pechkin 从NuGet程序管理器中获得Pechkin,代码示例如下: ...
- Error after SQL Server 2012 installation: Login Failure for "SQL Server Integration Services 11.0" SSIS service
When you install SQL Server 2012 and you try to connect to SSIS services, you cannot due to that the ...
- 理解URI
---恢复内容开始--- 参考 https://zh.wikipedia.org/wiki/%E7%BB%9F%E4%B8%80%E8%B5%84%E6%BA%90%E6%A0%87%E5%BF%97 ...
- Linux嵌入式文件系统(网络文件系统)
<文件系统定义> 怎么将文件和文件目录加载到linux内核中,这一种加载的方式就叫做文件系统 <建立根文件系统目录和文件> <创建目录> 1)在linux系统中使用 ...
- UVA1378 A funny stone game
博弈论. 就是有一堆石子你拿走一堆中的一个,然后再向后面两堆中加两个问胜负 i<j<=k 所以我们可以直接通过sg函数计算,考虑问题的奇偶性,如果这一位是奇的我们才考虑,偶的可以模仿 然后 ...
- Beego 和 Bee 的开发实例
Beego不是一般的web开发包.它构建在大量已存在的Go之上,提供了许多的功能,以下是提供的功能: 一个完整的ORM 缓存 支持session 国际化(i18n) 实时监测和重载 发布支持 ==== ...
- 【10.7校内测试】【队列滑窗】【2-sat】【贪心+栈二分+线段树(noip模拟好题)】【生日祭!】
比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; ...