• 【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 = 0;
        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 = 0;
        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 0;
    }
    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", 3, 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 0;
    }

    7.12

    就知道这题有坑。

    prog1.cpp: In constructor 'Sales_data::Sales_data(std::istream&)':
    prog1.cpp:13:17: error: 'read' was not declared in this scope
       read(is, *this);

    翻了一下收藏的博客,发现这道题要用友元函数(下一小节)。

    7.13

    参考(不会写)。

    Sales_data total(cin);
        if (total.units_sold > 0) {
            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 = 0;
            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#的GroupBy方法是如何工作的
    流媒体技术探索(一)
    战争雷霆-鼠标穿透
    继承与ER图
    从零开始的文档对象模型(结束更新)
    [hackerrank] booking.com
    [lintcode][美国大公司][1.字符串处理]
    [interview] Aug. 2015
    [codility] Lesson 2 Counting Elements
    [codility] Lesson 1 Time Complexity
  • 原文地址:https://www.cnblogs.com/xkxf/p/6673202.html
Copyright © 2020-2023  润新知