【c++ primer, 5e】访问控制与封装
练习
7.16
无,类的接口定义在public说明符之后,类的实现细节定义在private说明符之后。
7.17
有。类成员的默认访问权限不同。class的类成员默认为private,struct的则默认为public。
通常来说,当我们希望定义的类的所有成员是public的时候就用struct。
7.18
p242
【友元】
练习
7.20
声明的类外函数需要直接引用类内的私有成员的时候要用到友元函数。
设计原因:并非所有的、与某个类相关的函数都适合声明成那个类的成员函数,例如书上的add(obj, obj);
利弊:不详。。。
7.21
遇到问题了。已经声明成友元函数还是不能访问私有数据???
#include <iostream>
#include <string>
using namespace std; // Sales_data.h
class Sales_data {
friend Sales_data add(const Sales_data&, const Sales_data&);
friend ostream &print(ostream&, const Sales_data&);
friend istream &read(iostream&, Sales_data&);
public:
Sales_data() = default;
Sales_data(const string &s): bookNo(s) {}
Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) {}
Sales_data(istream&);
std::string isbn() const { return bookNo; }
Sales_data& combine(const Sales_data&);
double avg_price() const;
private:
string bookNo;
unsigned units_sold = ;
double revenue = 0.0;
};
// Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
ostream &print(ostream&, const Sales_data&);
istream &read(iostream&, Sales_data&); // Sales_data.cpp
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
istream &read(istream &is, Sales_data &item)
{
double price = ;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
double Sales_data::avg_price() const {
if (units_sold)
return revenue/units_sold;
else
return ;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
Sales_data::Sales_data(istream &is)
{
read(is, *this);
} // main.cpp
int main()
{
Sales_data data1; // default
Sales_data data2("ISOD233");
Sales_data data3("ISOD233", , 22.5);
Sales_data data4(cin); print(cout, data1) << endl;
print(cout, data2) << endl;
print(cout, data3) << endl;
print(cout, data4) << endl;
/* output:
0 0
ISOD233 0 0 0
ISOD233 3 67.5 22.5
DASD23 4 88 22
*/
return ;
}
编译结果如下:
$ g++ prog1.cpp -std=c++
prog1.cpp: In function 'std::istream& read(std::istream&, Sales_data&)':
prog1.cpp::: error: 'std::__cxx11::string Sales_data::bookNo' is private
string bookNo;
^
prog1.cpp::: error: within this context
is >> item.bookNo >> item.units_sold >> price;
^
prog1.cpp::: error: 'unsigned int Sales_data::units_sold' is private
unsigned units_sold = ;
^
prog1.cpp::: error: within this context
is >> item.bookNo >> item.units_sold >> price;
^
prog1.cpp::: error: 'double Sales_data::revenue' is private
double revenue = 0.0;
^
prog1.cpp::: error: within this context
item.revenue = price * item.units_sold;
^
prog1.cpp::: error: 'unsigned int Sales_data::units_sold' is private
unsigned units_sold = ;
^
prog1.cpp::: error: within this context
item.revenue = price * item.units_sold;
已改正:
#include <iostream>
#include <string>
using namespace std; // Sales_data.h
class Sales_data {
friend Sales_data add(const Sales_data&, const Sales_data&);
friend ostream &print(ostream&, const Sales_data&);
friend istream &read(istream&, Sales_data&);
public:
Sales_data() = default;
Sales_data(const string &s): bookNo(s) {}
Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) {}
Sales_data(istream&);
std::string isbn() const { return bookNo; }
Sales_data& combine(const Sales_data&);
double avg_price() const;
private:
string bookNo;
unsigned units_sold = ;
double revenue = 0.0;
};
// Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
ostream &print(ostream&, const Sales_data&);
istream &read(istream&, Sales_data&); // Sales_data.cpp
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
istream &read(istream &is, Sales_data &item)
{
double price = ;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
double Sales_data::avg_price() const {
if (units_sold)
return revenue/units_sold;
else
return ;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
Sales_data::Sales_data(istream &is)
{
read(is, *this);
} // main.cpp
int main()
{
Sales_data data1; // default
Sales_data data2("ISOD233");
Sales_data data3("ISOD233", , 22.5);
Sales_data data4(cin); print(cout, data1) << endl;
print(cout, data2) << endl;
print(cout, data3) << endl;
print(cout, data4) << endl;
/* output:
0 0
ISOD233 0 0 0
ISOD233 3 67.5 22.5
DASD23 4 88 22
*/
return ;
}
声明多写了一个o。
7.22
#include <iostream>
#include <string>
using namespace std; // Person.h
class Person {
friend istream &read(istream &is, Person &p);
public:
Person() = default;
Person(const string &name): name(name) {}
Person(const string &name, const string &address): name(name), address(address) {}
Person(istream&);
string getName() const { return name; }
string getAddress() const { return address; }
private:
string name;
string address;
};
istream &read(istream&, Person&);
ostream &print(ostream&, const Person&); // Person.cpp
istream &read(istream &is, Person &p)
{
is >> p.name >> p.address;
return is;
}
ostream &print(ostream &os, const Person &p)
{
os << p.getName() << " " << p.getAddress();
return os;
}
Person::Person(istream &is)
{
read(is, *this);
} // main.cpp
int main()
{
Person p1;
Person p2("xklf");
Person p3("llyy", "china");
Person p4(cin);
print(cout, p1) << endl;
print(cout, p2) << endl;
print(cout, p3) << endl;
print(cout, p4) << endl;
return ;
}
【c++ primer, 5e】访问控制与封装的更多相关文章
- 【c++ primer, 5e】函数声明 & 分离式编译
p186~p188: 函数声明1.函数只能定义一次,但是可以声明多次. 2.函数的接口:返回类型 + 函数名 + 形参类型 3.为什么要在头文件中进行函数声明???在源文件中定义?暂时理解到,这么做可 ...
- 【c++ primer, 5e】【函数基础】
p182~p185: 函数1.在调用函数和执行return语句的同时,也发生了控制权的转移. 2.函数返回值不能是一个数组.(但是可以返回一个包含数组的对象,或者指向数组的指针) 3.重要概念:名字的 ...
- 【c++ primer, 5e】【try语句块】
p172~p177:c++的try语句块和异常处理: 1.通常,与用户交互的代码和对象相加(底层的代码)是分离开的,异常由与用户交互的代码处理(底层代码抛出异常就可以了). 2.C++的runtime ...
- 【c++ primer, 5e】构造函数 & 拷贝、赋值和析构
[构造函数] 1.构造器就是创建对象时被调用的代码. 2.如果没有自定义构造器,那么编译器将自动合成一个默认的无参构造器. 3.自定义的构造器不允许加const,所创建const的对象只有在构造器代码 ...
- 【c++ primer, 5e】定义类相关的非成员函数
练习 7.6 & 7.7 #include <iostream> #include <string> using namespace std; // Sales_dat ...
- 【c++ primer, 5e】设计Sales_data类 & 定义改进的Sales_data类
[设计Sales_data类] 1.考虑Sales_data类应该有那些接口. isbn.combine.add.read.print... 2.考虑如何使用这些接口. Sales_data tota ...
- 【c++ primer, 5e】函数指针
简单的示例: #include <iostream> using namespace std; int sum(int x, int y) { return x + y; } int ma ...
- 【c++ primer, 5e】函数匹配
练习 6.49 候选函数:与所调用的函数的名字相同的函数的集合. 可行函数:给候选函数加上参数数量.参数类型的约束所得到的函数的集合. 6.50 a 3.4可行,二义匹配 b 2.4可行,2是最佳匹配 ...
- 【c++ primer, 5e】特殊用途语言特性
[默认实参] 1.注意点:函数的默认实参可以在函数的声明中添加,但是后续声明只能添加默认参数而不能改变先前声明的默认参数.(函数的声明通常是定义在头文件上的,多次声明同一个函数是合法的) 2.默认实参 ...
随机推荐
- Android开源-NineOldAndroids
开源地址: https://github.com/JakeWharton/NineOldAndroids 简单介绍:NineOldAndroids是一款支持在低版本号开发的Android动画的框架 包 ...
- 【SR】MAP
MAP:最大后验概率(Maximum a posteriori) 估计方法根据经验数据获得对难以观察的量的点估计.它与最大似然估计中的 Fisher方法有密切关系, 但是它使用了一个增大的优化目标,这 ...
- Android版微信小代码(转)
以下代码仅适用于Android版微信: //switchtabpos:让微信tab更贴合Android Design 如果你并不喜欢微信Android版和iOS端同用一套UI,现在有一个小方法可以实现 ...
- 使用JMAP dump及分析dump文件
查看整个JVM内存状态 jmap -heap [pid]要注意的是在使用CMS GC 情况下,jmap -heap的执行有可能会导致JAVA 进程挂起 查看JVM堆中对象详细占用情况jmap -his ...
- MySQL设置密码的三种方法
其设置密码有三种方法: a. ./mysqladmin -u root -p oldpassword newpasswd(记住这个命令是在/usr/local/mysql/bin中外部命令) b. S ...
- GitHub上整理的一些工具【转】
技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...
- 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP
[BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...
- 170111、MapperScannerConfigurer处理过程源码分析
前言 本文将分析mybatis与spring整合的MapperScannerConfigurer的底层原理,之前已经分析过java中实现动态,可以使用jdk自带api和cglib第三方库生成动态代理. ...
- Openstack创建镜像
如何创建生产用的Openstack镜像 参考官方文档https://docs.openstack.org/image-guide/centos-image.html 1,创建虚拟机硬盘 qemu-im ...
- php 正则表达式二.基本语法
官方手册正则语法:http://php.net/manual/zh/reference.pcre.pattern.syntax.php 正则表达式在线测试工具:regexpal 正则表达式的匹配先后顺 ...