其他分享
首页 > 其他分享> > 7-1 类的定义与构造函数

7-1 类的定义与构造函数

作者:互联网

image-20220220082407023

目录

7.1.1 定义Sale_data类

目标代码

弄懂下面的代码

#include<iostream>
using namespace std;
struct Sale_data{
    //关于Sale_data对象的操作函数
    string ibsn() const {return bookNo;}
    Sale_data& combine(Sale_data& );
    double avg_price() const;
    //数据成员
    string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
Sale_data& Sale_data::combine(Sale_data& trans){
    units_sold += trans.units_sold;
    revenue += trans.revenue;
    return *this;
}
double Sale_data::avg_price() const{
    if(units_sold != 0)
        return revenue/units_sold;
    else
        return 0;
}
//非成员函数接口
istream &read (istream &, Sale_data &);
ostream &print(ostream &, Sale_data &);

成员函数可以定义在类的内部,也可以定义在类的外部,但定义在外部需要加上定位符

引入this

每一个成员函数都会有一个隐式参数来访问调用对象的地址,this

string ibsn() const实际上被编译为string ibsn(&total) const

total是一个Sale_data对象

this 是调用对象的地址,即非常量指针,而我们知道,如果调用对象是一个常量对象,那么,this就必须是一个常量指针才能指向该调用对象,而this又是隐式参数,那么如何使this变成一个const指针呢?

C++语言的做法是允许把 const关键字放在成员函数的参数列表之后

而this为const指针的成员函数就成为常量成员函数

常量对象,常量对象的引用和指针都只能使用常量成员函数

成员的编译顺序

先编译成员,再编译成员函数

用this返回调用对象的引用

Sale_data& conbine(Sale_data& )的实现中return *this;表示返回调用对象。

注:参数使用引用传入是因为拷贝传入需要复制,会有额外开销

为什么需要返回类型是对象的引用而不是非引用?

为了链式使用成员函数

一个const成员函数以引用形式返回*this,那么该引用必须为常量引用

非成员函数

实现与测试函数

istream &read(istream &is, Sale_data &item){
    double price = 0;
    is >> item.bookNo >>item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}
ostream &print(ostream &os, Sale_data &item){
    os << item.bookNo << " " << item.units_sold << " "
       << item.revenue<<endl;
    return os;
}
int main(){
    Sale_data item;
    read(cin, item);
    print(cout, item);
    return 0;
}

readprint的写法可以视为模板直接记下来,重点是函数三要素

7.1.2 构造函数

目标代码

struct Sale_data{
    //新增的构造函数
    Sale_data() = default;
    Sale_data(string s) : bookNo(s) {}
    Sale_data(string s, unsigned n, double p) : 
              bookNo(s), units_sold(n), revenue(n*p) {}
    Sale_data(istream &);
    /*
      . . .
      . . .
    */
}
//非成员函数
//定义在外部的构造函数
Sale_data::Sale_data(istream &is){
    read(is, *this);
}
//外部成员函数

构造函数的特点

合成的默认构造函数

默认构造函数

没有实参的构造函数称为默认构造函数,编译器创建的默认构造函数称为合成的默认构造函数

默认构造函数按如下规则进行初始化:

类内初始值只能用“=”或者“{}”

某些类不能依赖合成的默认构造函数

=default 的含义

Sale_data() = default

表示手动添加默认构造函数,且该默认构造函数的作用等价于合成的默认构造函数

构造函数的初始值列表

Sale_data(string s) : bookNo(s) {}

Sale_data(string s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(n*p) {}

有一点需要注意,在上面的两个构造函数中函数体都是空的。这是因为这些构造函数的唯一目的就是为数据成员赋初值,一旦没有其他任务需要执行,函数体也就为空了。

在类的外部定义的构造函数

//定义在外部的构造函数
Sale_data::Sale_data(istream &is){
    read(is, *this);
}

由于构造函数是定义在类的外部,所以需要定位符Sale_data::由于是构造函数,所以函数名也为Sale_data,故为Sale_data::Sale_data

这个构造函数没有构造函数初始值列表,或者讲得史准确一点,它的构造函数初始值列表是空的。尽管构造函数初始值列表是空的,但是由于执行了构造函数体,所以对象的成员仍然能被初始化。

7.1.3 完整代码1

#include<iostream>
using namespace std;
struct Sale_data{
    //新增的构造函数
    Sale_data() = default;
    Sale_data (string s) : bookNo(s) {}
    Sale_data(string s, unsigned n, double p) : 
              bookNo(s), units_sold(n), revenue(n*p) {}
    Sale_data(istream &);
    //关于Sale_data对象的操作函数
    string ibsn() const {return bookNo;}
    Sale_data& combine(Sale_data& );
    double avg_price() const;
    //数据成员
    string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
//非成员函数接口
istream &read (istream &, Sale_data &);
ostream &print(ostream &, Sale_data &);
//外部构造函数(可以写在内部)
Sale_data::Sale_data(istream &is){
    read(is, *this);
}

istream &read(istream &is, Sale_data &item){
    double price = 0;
    is >> item.bookNo >>item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}
ostream &print(ostream &os, Sale_data &item){
    os << item.bookNo << " " << item.units_sold << " "
       << item.revenue<<endl;
    return os;
}
//外部成员函数(可以写在内部)
Sale_data& Sale_data::combine(const Sale_data& trans){
    units_sold += trans.units_sold;
    revenue += trans.revenue;
    return *this;
}
double Sale_data::avg_price() const{
    if(units_sold != 0)
        return revenue/units_sold;
    else
        return 0;
}

int main(){
    Sale_data item(cin);
    print(cout, item);
    return 0;
}

类的结构图

image-20220130215129167

public与private见 7-2 笔记

标签:string,bookNo,Sale,默认,构造函数,data,定义
来源: https://www.cnblogs.com/timothy020/p/15914812.html