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 ...
随机推荐
- 【转载】Node.js 教程(菜鸟教程系列)
很好的一篇教程:Node.js 教程 简单做下笔记 概述 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立 ...
- loadrunner添加变量检查点
LoadRunner设置登陆检查点 login() { lr_think_time(); web_url("passport2", "URL=http://test232 ...
- Ionic 自动创建应用的图标与启动画面
你只需要一个目录和两张图片就可以搞定.图片可以是 .png 的,Photoshop的 .psd,或者Illustrator的 .ai,(例如)命名为icon.png和splash.png.把这些图片放 ...
- IAR搭建unity框架
1. 新建工程 2. 增加组 unit,并加入相应源码 3. 增加需要测试的API源文件 4. 编写相应的测试用例 编译,download and debug view->TerminalIO ...
- Python 中的面向对象和异常处理
在之前我们已经说过了 Python 中内置的主要的几种对象类型,(数,字符串,列表,元组和字典).而面向对象的核心人物还没出场呢 .那么我们常说的对象是什么类型的呢,其实他的类型就是“类”.继承封装和 ...
- 1019 General Palindromic Number (20)(20 point(s))
problem A number that will be the same when it is written forwards or backwards is known as a Palind ...
- python opencv3 检测人
git:https://github.com/linyi0604/Computer-Vision # coding:utf-8 import cv2 # 检测i方框 包含o方框 def is_insi ...
- NOI.AC WC模拟赛
4C(容斥) http://noi.ac/contest/56/problem/25 同时交换一行或一列对答案显然没有影响,于是将行列均从大到小排序,每次处理限制相同的一段行列(呈一个L形). 问题变 ...
- Lunix/Mac下根据最后修改时间复制文件和文件夹,保持原有的目录结构
度娘知道:http://zhidao.baidu.com/link?url=DD47jm6qDgT7yxsnz9e-NC4Fqd33oRoiIwcGLkw5TL4cbf50VKY2IONbHKH0IE ...
- OpenGL和GLSL版本更迭
前言 最近才发现,自己写的glsl和教程的glsl版本对不上,一直以为是xcode不允许使用太高版本,只能使用OpenGL 2.0的版本,却不知使用glfw可以使用到最新的OpenGL版本.