【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 : ...
随机推荐
- JavaScript匿名函数的使用
JavaScript匿名函数的使用: http://www.cnblogs.com/skykang/archive/2010/12/03/1895274.html 一.什么是匿名函数? 在Javas ...
- android中Animation动画的连续播放与播放完毕后停留在最后的状态
我们做安卓应用的苦逼程序员们常常会需要用到Animation也就是动画.比如做地图功能的时候.我们在手机旋转时需要根据手机重力感应来调整地图的角度,让它上面的“北”一直指向地球的北面...好多人做动画 ...
- a 标签 download 和 target 不配合
发现一个奇怪的事,看代码 <a id="downloadAlink" target="_blank" href="http://www.baid ...
- 01.Elasticsearch安装
1.下载运行Elasticsearch 1.下载解压elasticsearch Elasticsearch官网地址:https://www.elastic.co/ Elasticsearch最新版下载 ...
- Zipline Data Bundles
Data Bundles A data bundle is a collection of pricing data, adjustment data, and an asset database. ...
- 前端开发 - JQuery - 上
一.js的缺点 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- Tr A--hdu1575(矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575 算是模板吧 #include <iostream> #include <std ...
- MPI Maelstrom---poj1502(最短路模板)
题目链接:http://poj.org/problem?id=1502 题意:求从处理器1到其它处理器所需的最少时间是多少: 输入是下三角,如果是x表示A[i][j]不能直接联系: #include ...
- rabbitMQ 安装,集群搭建, 编码
RabbitMQ 一.背景 命令行工具: http://www.rabbitmq.com/man/rabbitmqctl.1.man.html 介绍入门文章: http://blog.csdn.net ...
- Linux上的下载软件uGet
uGet是一款开源下载软件,类似于我们常用的迅雷,不过uGet支持的操作系统非常多,Ubunut,Arch,openSUSE,Windows,MacOS,BSD等. uGet支持两个下载引擎:curl ...