C++ Primer Plus的若干收获--(九)
这篇博文我接着上一篇来写,相同讲一些关于类的一些基础知识。
本篇将会继续使用上篇的股票类STock,这里给出接口
ifndef STOCKOO_H_
#define STOCKOO_H_
#include<string> class Stock
{
private:
std::string company;//公司名称
long shares;//所持股票的数量
double share_val;//每股的价格
double total_val;//股票总值
void set_tot(){total_val=shares*share_val;}
public:
Stock(const std::string& co,long n=0,double pr=0.0);
Stock();
void acqure(const std::string&co, long n,double ptr);//获得股票
void buy(long num,double price);//增持
void sell(long num,double price);//卖出股票
void update(double price);//更新股票价格
void show() const;//显示关于所持的股票信息
};
#endif // STOCKOO_H_
9.1 对象数组
实际上。声明对象数组的方法与声明标准类型的数组的方法同样:
Stock mystuff[4];
前面讲过。当程序创建未被现实初始化的对象数组时,总是调用默认构造函数。上述声明要求,这个类要么没有显式的定义不论什么构造函数(这样的情况下,将使用不运行不论什么操作的隐式默认构造函数),要么定义了一个显式的默认构造函数。每一个元素都是一个Stock对象。
我们也能够利用多种构造函数来初始化我的对象数组
const int STK=10;
Stock stocks[STK]={
Stock("NAnoSmart",12.5,20),
Stock(),
Stock("Monolithis",130,2.5),
};
9.2 类作用域
在类定义的名称的作用于都为整个类,作用域为整个类的名称仅仅在该类中是已知的,在类外是不可知的。因此。能够在不同类中使用同样的类成员名而不会引起冲突。
比方。Stock类的shares成员不同于JobRide的shares成员。
另外。类的作用域意味着不能从外部直接訪问类的成员,共同拥有成员函数也是如此。也就是说,要调用公有成员函数。必须通过对象。
总之,在类声明或成员函数定义中。能够使用维修时的成员名称。构造函数在被调用时,才干被识别,由于它的名称与类名同样。在其它情况下,使用类成员名时,必须依据上下文使用直接成员运算符(.),间接成员运算符(->)。或者是作用域解析符(::)。
有时候。使用符号常量的作用域为类含实用。
假设我写下例如以下代码,您可能觉得这样做是可行的
class Bakery
{
private:
const int Months=12;
double costs[Months];
...
}
可是这是行不通的,由于声明类仅仅是描写叙述了对象的形态,并没有创建对象。
因此在创建对象前。将没有存储值的空间。
然而,有两种方式能够实现这个目标,而且效果同样。第一种是在类声明中声明一个枚举。在类声明中声明的枚举作用域为整个类,因此能够用枚举为整形常量提供作用域为整个类的符号名称。则上述代码能够这样写
class Bakery
{
private:
enum{Months=12};
double costs[Months];
...
}//这样的声明方式的枚举并不会创建类数据成员。也就是说全部对象都不会包括枚举。<strong>Month仅仅是一个符号名称。 </strong>
还有一种方式是使用keyword——static
class Bakery
{
private:
static const int Months=12;
double costs[Months];
...
}
这个样将创建一个名为MOnth的常量,该常量将其与其它的静态变量存储在一起,而不是存储在对象中。
9.3 抽象数据类型
Stock类很详细。然而,程序猿经常通过定义类来表示更通用的概念。比如,就实现计算机专家所说的抽象数据类型(ADT)。顾名思义。ADT以通用的方式描写叙述数据类型,而没有引入语言或是实现细节。这里简要的给出栈的接口
ifndef STACK_H_
#define STATC_H_
typedef unsigned liong Item; class Stack
{
private:
enum{Max=10};
Item items[10];
int top;
public:
Stack();
bool isempty() const;
bool isfull();
bool push(const Item &item);
bool pop(Item& item);
}; #endif // STACK_H_
接下来将会进入到类的使用部分
9.4 运算符重载
运算符重载是一种形式的C++多态。
在这之前我们介绍过函数的重载或称为函数的多态。旨在让您可以使用同名的函数来完毕同样的基本操作。
运算符重载将重载的概念扩展到运算符上,匀速赋予C++运算符多种含义。要重载运算符,需使用被称为运算符函数的特殊函数形式。其格式例如以下:
<span style="font-size:18px;">operatorop(argument-list)</span>
比如,operator+()重载+运算符,operate*()重载*运算符。
op必须是一个有效的C++运算符,不能虚构一个新的运算符。不能重载@这个符号。
以下我们来看一个运算符重载的演示样例:计算时间
ifndef MYTH0_H_
#definr MYTH0_H_ class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h,int m=0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h=0,int m=0);
Time Sum(const Time & t)const;
void show() const;
};
#endif // MYTH0_H_
这里给出mytime0.cpp
include<iostream>
#include"mytime0.h" Time::Time()
{
hours=minutes=0;
} Time::Time(int h,int m)
{
hours=h;
minutes=m;
} void Time::AddMin(int m)
{
minutes+=m;
hours+=minutes/60;
minutes%=60;
} void Time::AddHr(int h)
{
hours+=h;
} void Time::Reset(int h,int m)
{
hours=h;
minutes=m;
} Time Time::Sum(const Time& t)const
{
Time sum;
sum.minutes+t.minutes;
sum.hours=hours+t.hours+sum.minutes/60;
sum.minutes%=60;
return sum;
} void Time::Show() const
{
std::cout<<hours<<"hours,"<<minutes<<"minutes";
}
这个类比較基础,我就简单的说一下当中的一个函数Sum()。
注意參数是引用,但返回的却不是引用。将參数声明为引用的目的是为了提高效率。假设按值传递Time对象,功能同样,可是效率明显不如引用。
可是返回值不能是引用。因为sum是一个局部变量,当函数调用结束时,这个变量将不再存在。因此引用将指向一个不存在的变量。使用返回类型Time意味着程序将在删除sum之前构造它的拷贝。调用该函数将得到它的拷贝。
9.5 加入重载运算符
以下我们来给上面的函数加入重载函数。用operate+()来替换上述的sum()函数
Time Time::operator+(const Time& t)const
{
Time sum;
sum.minutes=sum.minutes+t.minutes;
sum.hours=hours+t.hours+sum.minutes/60;
sum.minutes%=60;
return sum;
}
这样我们就能够这样调用operator+()方法
total=coding.operator+(fixing); total=coding+fixing;//二者等价
这两种方法都将调用operator方法。
注意,在运算符表示法中,运算符左側的对象时调用对象。运算符右側的对象是作为參数被传递的对象。
因此这种代码也是能够的
Time t1,t2,t3,t4;
t4=t1+t2+t3;//valid</span>
9.6 重载的限制
多数C++运算符都能够这种方式重载。
重载的运算符不必是成员函数,但必须至少是有一个操作数是用户定义的类型。以下具体介绍其限制:
(1)重载后的运算符必须至少有一个操作数使用户定义的类型,这将防止用户为标准类型重载运算符。比方。不能将-运算符用来计算两个数的和。
(2)使用运算符时不能违反运算符原来的句法规则,比方,不饿能将%重载成一个操作数。也不能改动其优先级。
(3)不能创建新的运算符,如@。
(4)不能重载以下的运算符
- sizeof:sizeof运算符;
- . :成员运算符;
- :::作用域解析运算符;
- ?::条件运算符;
- const_cast:强制类型转换运算符;
- dynamic_cast:强制类型转换运算符;
- static_cast:强制类型转换运算符;
(5)多数运算符都能够通过成员或非成员函数进行重载,可是以下的运算符仅仅能通过成员函数进行重载。
- =:赋值运算符;
- ():函数调用运算符;
- 【】下标运算符。
- ->:通过指针訪问成员运算符
好了,这次就到这里吧。
好累啊,手都酸了。
。
。
C++ Primer Plus的若干收获--(九)的更多相关文章
- C++ Primer Plus的若干收获--(二)
哎,真是不想吐槽考驾照的艰辛历程了.跑到大西郊,顶着大太阳,一天就能摸上个十几分钟二十分钟的车,简直不要太坑爹,这两天真是做的我屁股疼的不行. .. 今天果断不去了.仅仅可惜我的大阿根廷啊,坚持到最后 ...
- C++ Primer Plus的若干收获--(三)
有时候怀疑真是怀疑自己走的路究竟是不是正确的.作为一个土生土长数学系学生,却对数学毫无兴趣,没事的时候就喜欢躲在图书馆看看有关计算机的书.有时候期末考试时候会挂个一两门的数学专业课,有时候真希望数学课 ...
- C++ Primer Plus的若干收获--(十一)
本篇主要讲了转换函数的利与弊以及简要介绍流与iostream文件 因为在本篇仍然要使用上篇的Stonewt类,这里首先给出其代码 <span style="font-size:18px ...
- 学习C++ Primer 的个人理解(九)
这一章介绍顺序容器,在之前的第三章中,了解到的vector就属于顺序容器的一种. 一个容器就是一些特定类型对象的集合. 除了vector,还有哪些顺序容器? vector: 大小可变,随机访问的速度很 ...
- C Primer Plus学习笔记(九)- 数组和指针
数组 数组由数据类型相同的同一系列元素组成 需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型 普通变量可以使用的类型,数组元素都可以用 float candy[365]; // ...
- C++ Primer Plus读书笔记(九)内存模型和名称空间
1.作用域和链接 int num3; static int num4; int main() { } void func1() { static int num1; int num2; } 上边的代码 ...
- C语言培训第一天
下面是一些命令,先来谈谈今天的若干收获吧! 计算机中的一切文件都是以二进制补码的形式存在,问题也就来了. 第一个问题 如果我们给一个无符号的数赋值一个负数,他会读取到什么,又会输出什么?(似乎问题和上 ...
- 【C++】《C++ Primer 》第十九章
第十九章 特殊工具与技术 一.控制内存分配 1. 重载new和delete new表达式的工作机理: string *sp = new string("a value"); //分 ...
- C++Primer 第十九章
//1.控制内存分配: //A:某些应用程序对内存分配有特殊的需求,因此我们无法将标准内存管理机制直接应用于这些程序.它们常常需要自定义内存分配的细节,比如使用关键字new将对象放置在特定的内存空间中 ...
随机推荐
- 经验总结21--抓取WEB数据,汇率,HtmlAgilityPack
网上找了非常多资料,PHP的比較多,然后找到有csv文件的.处理起来非常麻烦,国外的站点速度非常慢. 最后还是去页面上抓取数据,我是从中国银行抓取的,各位可去其它站点抓取. 1.模拟请求URL. st ...
- Android之弹出菜单框【注冊上下文菜单】
注冊上下文菜单:(长按弹出一个菜单) 第一种创建方法(与长按事件结合): public class MainActivity extends Activity { private TextView u ...
- codecombat之边远地区的森林1-11关及地牢38关代码分享
codecombat中国游戏网址:http://www.codecombat.cn/ 全部代码为javascript代码分享 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- 7.treeview
ui mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include < ...
- Oracle 新手语法记录
一.用户 1. 创建用户 语法:create user 用户名 identified by 口令; create user test identified by test; 2. 修改用户 语法:al ...
- Ubuntu包管理工具整理
概述 常用的包管理包含三类工具:dpkg.apt和aptitude.1 dpkg 主要是对本地的软件包进行管理,本地软件包包括已经在本地安装的软件包和已经下载但还没有安装的 deb 文件,不解决依赖关 ...
- http接口服务方结合策略模式实现总结
在项目中,我们经常会使用到http+xml的接口,而且不仅仅的是一个,可能会有多个http的接口需要实时的交互.但是http接口的接收消息的公共部分是一样的,只有每个接口的报文解析和返回报文是不同的, ...
- idea的项目中output框出现乱码
找到tomcat的安装目录中的logging.properties 我的在这里:E:\tools\tomcat\apache-tomcat-8.5.38\conf 改其中的参数 修改前 java.u ...
- Mysql-slowlog
MySQL慢查询日志是MySQL提供的一种日志记录,用来记录执行时长超过指定时长的查询语句,具体指运行时间超过 long_query_time 值的 SQL 语句,则会被记录到慢查询日志中. long ...
- Client初见——python
from socket import *ip_port = ('127.0.0.1',8080)back_log = 5buffer_size = 1024tcp_client = socket(AF ...