【c++ primer, 5e】构造函数 & 拷贝、赋值和析构
【构造函数】
1、构造器就是创建对象时被调用的代码。
2、如果没有自定义构造器,那么编译器将自动合成一个默认的无参构造器。
3、自定义的构造器不允许加const,所创建const的对象只有在构造器代码执行完后,才被赋予const性质。
4、如果自定义了构造器,那么默认的构造器将无效化,可以理解为自定义内容覆盖了默认的内容。—— “要么什么都不做,要么全部都交给你来做。”
5、构造函数使用类内初始值并不是一个坏选择。
6、default。(在练习中体现)
7、构造函数初始值列表。(在练习中体现)
练习
7.11
ps:定义在类内的函数默认为内联的!类外的不是。(内联函数可以提高性能,那么,为什么不把所有函数都定义成内联函数呢?内联函数的优缺点)
#include <iostream>
#include <string>
using namespace std; // Sales_data.h
struct Sales_data {
// 新增的构造函数
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&);
// public部分,对象看起来是怎么样的。
std::string isbn() const { return bookNo; } // inline function
Sales_data& combine(const Sales_data&);
double avg_price() const;
// private部分,数据成员。
std::string bookNo;
unsigned units_sold = ;
double revenue = 0.0;
};
// Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::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 0
ISOD233 0 0 0
ISOD233 3 67.5 22.5
DASD23 4 88 22
*/
return ;
}
7.12
就知道这题有坑。
prog1.cpp: In constructor 'Sales_data::Sales_data(std::istream&)':
prog1.cpp::: error: 'read' was not declared in this scope
read(is, *this);
翻了一下收藏的博客,发现这道题要用友元函数(下一小节)。
7.13
参考(不会写)。
Sales_data total(cin);
if (total.units_sold > ) {
Sales_data trans;
while (read(cin, trans)) {
if (total.isbn() == trans.isbn())
total.combine(trans);
else {
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
} else {
cerr << "No data?!" << endl;
}
7.14
是这样吗?
Sales_data()
{
units_sold = ;
revenue = 0.0;
}
7.15
测试无误。
// constructor
Person() = default;
Person(const string &name): name(name) {}
Person(const string &name, const string &address): name(name), address(address) {}
Person(istream&);
Person::Person(istream &is)
{
read(is, *this);
}
【拷贝、赋值和析构】
如果我们不主动定义这些操作,那么编译器将会替我们合成它们。
默认的析构函数将会在语句块结束时被调用,销毁局部变量。
某些类(管理动态内存的类)不能依赖于合成的版本,因此有时候不得不定义这些函数。
【c++ primer, 5e】构造函数 & 拷贝、赋值和析构的更多相关文章
- [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符
/* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...
- 构造函数和初始化表、this指针与常函数、析构函数、拷贝构造与拷贝赋值(day05)
十四 构造函数和初始化表 ... 初始化表 )语法形式 class 类名{ 类名(形参表):成员变量1(初值),...{} }; )必须要使用初始化表的场景 -->如果有类 类型的成员变量,而该 ...
- C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)
[1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...
- C++中的构造函数,拷贝构造函数和赋值运算
关于C++中的构造函数,拷贝构造函数和赋值运算,以前看过一篇<高质量C++/C编程指南>的文章中介绍的很清楚,网上能搜索到,如果想详细了解这方面的知识可以参看一下这篇文章. 常见的给对象赋 ...
- 关于C++中的拷贝构造函数和赋值函数
如果类定义的数据成员中存在指针或引用,那么最好重载这两个函数. 1. 定义 拷贝构造函数的定义格式:构造函数名(const 源类名& 引用对象形参名){} 赋值函数定义格式:源类名 & ...
- C++雾中风景6:拷贝构造函数与赋值函数
在进行C++类编写的过程之中,通常会涉及到类的拷贝构造函数与类的赋值函数.初涉类编写的代码,对于两类函数的用法一直是挺让人困惑的内容.这篇文章我们会详细来梳理拷贝构造函数与赋值函数的区别. 1.调用了 ...
- C++中:默认构造函数、析构函数、拷贝构造函数和赋值函数——转
对于一个空类,编译器默认产生4个成员函数:默认构造函数.析构函数.拷贝构造函数和赋值函数.1.构造函数:构造函数是一种特殊的类成员,是当创建一个类的时候,它被调用来对类的数据成员进行初始化和分配内存. ...
- 【C++】拷贝构造函数和赋值符函数
在C++中,调用拷贝构造函数有三种情况: 1.一个对象作为函数参数,以值传递的方式传入函数体. 2.一个对象作为函数返回值,以值传递的方式从函数返回. 3.一个对象用于给另外一个对象进行初始化(复制初 ...
- CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数
类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 // person.h #ifndef _PERSON_H_ #define _PERSON_H_ class Person{ public : ...
随机推荐
- 用Java向数据库中插入大量数据时的优化
使用jdbc向数据库插入100000条记录,分别使用statement,PreparedStatement,及PreparedStatement+批处理3种方式进行测试: public void ex ...
- Delphi XE5通过WebService开发Web服务端和手机客户端
Delphi XE5通过WebService开发Web服务端和手机客户端介绍 我们开发一个三层的android程序 建立一个webservices stand-alone vcl applicati ...
- JAVA基础之sql模糊匹配、外键以及jsp中include的用法
一.SQL模糊匹配 适用于对字符串进行模糊搜索 格式: 字段名 Like '%关键词%' % 表示这个位置可有任意个字符(没有也可以) %关键词% 只要包含关键词就算 ...
- mysql状态分析之show global status
这里整理下mysql global status的相关命令,在计算监控数据的时候需要用到 一.慢查询 show variables like '%slow%'; +------------------ ...
- 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活--hdu2191(多重背包模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 标准的多重背包 题目 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是 ...
- Python中的高级数据结构(转)
add by zhj: Python中的高级数据结构 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数 ...
- mysql 正则表达式 regexp rlike not rlike
regexp rlike not rlike 今天在上班的时候突然遇到了一个问题,C+组的同事要删除mysql里面的一些特殊数据,想要正则进行匹配.于是问我,没想到还真的把我难住了,问题如下 ...
- Mybatis框架学习总结-Mybatis框架搭建和使用
Mybatis介绍 Mybatis是一个支持普通SQL查询,存储过程,和高级映射的优秀持久层框架.Mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.Mybatis可以使 ...
- 把typora改为微软雅黑+Consolas
前言 typora是一款非常方便的书写markdown文本的编辑器.官网:https://www.typora.io/ 对于字体强迫症患者来说,不把字体改成微软雅黑+Consolas,那是相当难受.本 ...
- 打开关闭oracle自动表分析
oracle 表的统计信息,跟他的执行计划很有关联 执行计划的正常是否,跟SQL的执行速度很有关系 首先讲解一下如何查看一个数据库的是否开启自动统计分析 1.查看参数:STATISTICS_LEV ...