我是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成员继承问题的更多相关文章

  1. [转]java中作用域public private protected 以及不写的区别

    在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes,认为都是自己的朋友 ...

  2. Java中public,private,protected,和默认的区别

    Java中public,private,protected,和默认的区别 1.private修饰词,表示成员是私有的,只有自身可以访问: 2.protected,表示受保护权限,体现在继承,即子类可以 ...

  3. php class中public,private,protected的区别,以及实例

    一,public,private,protected的区别 public:权限是最大的,可以内部调用,实例调用等. protected: 受保护类型,用于本类和继承类调用. private: 私有类型 ...

  4. 访问权限系列一(public/private/protected/default):成员变量

    通过两个程序包对自身或互相之间的访问,得到结果.(先编译Test_01,得到class文件,通过Test的集中访问情况) 如下Test.java中内容: package com.java; /* * ...

  5. PHP中const,static,public,private,protected的区别

    原文地址:http://small.aiweimeng.top/index.php/archives/54.html const: 定义常量,一般定义后不可改变static: 静态,类名可以访问pub ...

  6. PHP中public,private,protected,abstract等关键字用法详解

    PHP中常用的关键字 在PHP中包含了很多对函数和类进行限制的关键字,常用的通常有abstract,final,interface,public,protected,private,static等等, ...

  7. public/private/protected访问控制权限的区别

    //public/private/protected访问控制权限的区别//时间:2016/8/16 //(一)修饰成员: //public: 在类内.类外都能使用 . //protected: 在类内 ...

  8. 深入浅出OOP(五): C#访问修饰符(Public/Private/Protected/Internal/Sealed/Constants)

    访问修饰符(或者叫访问控制符)是面向对象语言的特性之一,用于对类.类成员函数.类成员变量进行访问控制.同时,访问控制符也是语法保留关键字,用于封装组件. Public, Private, Protec ...

  9. public private protected和默认的区别(转自百度)

    public private protected和默认的区别 Java中对类以及类中的成员变量和成员方法通过访问控制符(access specifier)进行区分控制.刚学Java语言的同学可能对pu ...

  10. 【转】C++ 类访问控制public/private/protected探讨

    示例1:---------------------------------------- class C{ int c1; int c2;public: void set(C* s, int i, i ...

随机推荐

  1. #CSS 文本溢出部分显示省略号

    单行结尾溢出: 用text-overflow:ellipsis属性实现,当然还需要加宽度width属来兼容部分浏览. width:300px;overflow: hidden; text-overfl ...

  2. #define const typedef

    #define用法 1. 定义简单的常数:定义常量,便于修改 #define N 1000 2. 定义简单的函数:注意多使用括号 define可以像函数那样接受一些参数,如下: #define max ...

  3. ueditor初始化

    一.下载文件复制到项目中 二.复制表情文件 三.复制列表图片 四.修改ueditor.config.js文件 五.接着修改net文件下config.json文件 六.完蛋了,不支持IE8,版本替换为了 ...

  4. USACO 6.4 Wisconsin Squares

    Wisconsin Squares It's spring in Wisconsin and time to move the yearling calves to the yearling past ...

  5. UIView中常见的方法汇总

    addSubview: 添加一个子视图到接收者并让它在最上面显示出来. - (void)addSubview:(UIView *)view  总结:这个方法同样设置了接收者为下一个视图响应对象.接收者 ...

  6. 使用ASP.NET MVC+Entity Framework快速搭建系统

    详细资料: http://www.cnblogs.com/dingfangbo/p/5771741.html 学习 ASP.NET MVC 也有一段时间了,打算弄个小程序练练手,做为学习过程中的记录和 ...

  7. 基于 Laravel 开发博客应用系列 —— 从测试开始(一):创建项目和PHPUnit

    1.创建博客项目 我们将遵循上一节提到的六步创建一个新 Laravel 5.1 项目的步骤,创建本节要用到的博客项目 —— blog. 首先,在本地主机安装应用骨架: nonfu@ubuntu:~/C ...

  8. 装饰 Markdown

    利用 Font Awesome 提升 Markdown 的表现能力 Font Awesome 是一个字体和图标工具包,包含人物.动物.建筑.商业.品牌等等各种主题丰富的图标符号,可以通过相应的语法添加 ...

  9. 百道CTF刷题记录(一)

    简介 最近在刷CTF题,主攻Web,兼职Misc Shiyanbar 0x01 简单的登陆题 简单概括: 考点: %00截断正则 CBC字节翻转攻击 难度: 难 WP:https://blog.csd ...

  10. 跟厂长学PHP7内核(二):源码分析的环境与工具

    本文主要介绍分析源码的方式,其中包含环境的搭建.分析工具的安装以及源码调试的基本操作. 一.工具清单 PHP7.0.12 GDB CLion 二.源码下载及安装 $ wget http://php.n ...