c++primer 练习题7.34-7.46

7.34-会报错,pos类型未定义
要把类型定义放在类开始的地方,就会确保后面的方法会使用它时不出现问题
7.35
书中原题

typedef string Type;
Type initVal(); 
class Exercise {
public:
    //这里再次起了相同的别名,不同编译器的处理不同
    //有的会报错,有的不会报错
    typedef double Type;
    Type setVal(Type);
    Type initVal(); 
private:
    int val;
};
Type Exercise::setVal(Type parm) { 
    val = parm + initVal();     
    return val;
}

问题在于

Type Exercise::setVal(Type parm) { //这个Type这样的话会被认为是string类型的
    val = parm + initVal();     
    return val;
}

要改成

Exercise::Type Exercise::setVal(Type parm) { //这样就是double类型的
    val = parm + initVal();     
    return val;
}

7.36:构造函数初始值的顺序与成员声明的顺序要一致
题目代码:

struct X {
    X (int i, int j): base(i), rem(base % j) {}
    int rem, base;
};

要改成

struct X {
    X (int i, int j): base(i), rem(base % j) {}
    int base,rem;
};

7.37

Sales_data first_item(cin); // 使用 Sales_data(std::istream &is) { read(is, *this); } 从is输入流中顺序读取对象的参数
int main() {
    Sales_data next; // bookNo = "", cnt = 0, revenue = 0.0

    // 使用 Sales_data(const std::string &s) :bookNo(s) {}  
    //  bookNo = "9-999-99999-9", cnt = 0, revenue = 0.0
    Sales_data last("9-999-99999-9"); 
}

7.38

    Sales_data(std::istream &is=std::cin) { read(is, *this); }

7.39

不合法。当你调用 Sales_data() 构造函数时,无法区分是哪个重载。

7.40

class employee{
public:
    //名字性别都不能改所以用const关键字,都采用地址传值
    employee(const std::string &a_name,std::string &a_dartment,const std::string &a_age,double &a_worklong)
            :name(a_name),dartment(a_dartment),age(a_age),work_long(a_worklong){}
    employee(std::istream &is) {is>>name>>dartment>>age>>work_long;}

private:
    std::string name;
    std::string dartment;
    std::string age;
    double work_long;

};

7.41 Sales_date类代码

#include <string>
#include <iostream>
using namespace std;
class Sales_data
{
friend std::istream &read(std::istream &is, Sales_data &item);
    friend std::ostream &print(std::ostream &os, const Sales_data &item);
    friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs);

public:
    //Sales_data(std::string s =""):bookNo(s){}
    //Sales_data(const std::string &s) :bookNo(s) {}
    Sales_data(const std::string s, unsigned cnt, double rev) :bookNo(s), units_sold(cnt), revenue(rev*cnt) {cout<<"三参构造函数"<<endl;}
    //Sales_data(std::istream &is=std::cin) { read(is, *this); }
    //委托构造函数,委托给三参构造函数
    Sales_data():Sales_data("",0,0){cout<<"默认构造函数"<<endl;}//直接委托给三参构造函数
    Sales_data(std::string s):Sales_data(s,0,0){cout<<"单参数构造函数"<<endl;}//三参构造函数
    Sales_data(std::istream &is):Sales_data(){
        cout<<"委托给默认构造函数"<<endl;
        read(is,*this);}//先委托给默认构造函数,默认构造函数再委托三参构造函数


    std::string isbn() const { return bookNo; };
    Sales_data& combine(const Sales_data&);

private:
    std::string bookNo;
    unsigned units_sold=0 ;
    double revenue =0.0;

    //计算平均收益的函数
    inline double avg_price() const;
};
Sales_data& Sales_data::combine(const Sales_data& rhs)//两个对象属性相加的方法
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

std::istream &read(std::istream &is, Sales_data &item)//从一个输入流读入一个对象
{
    double price = 0;
    is >> item.bookNo >> item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}

std::ostream &print(std::ostream &os, const Sales_data &item)//从一个输出流显示出对象信息
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue;
    return os;
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)//相同编号的对象相加的函数
{
    Sales_data sum = lhs;
    sum.combine(rhs);
    return sum;
}
 inline double Sales_data::avg_price() const{
    if(units_sold){
        return revenue/units_sold;
    }else{
        return 0;
    }
}

class employee{
public:
    employee(const std::string &a_name,std::string &a_dartment,const std::string &a_age,double &a_worklong)
            :name(a_name),dartment(a_dartment),age(a_age),work_long(a_worklong){}
    employee(std::istream &is) {is>>name>>dartment>>age>>work_long;}

private:
    std::string name;
    std::string dartment;
    std::string age;
    double work_long;

};

接下来是main函数创建对象查看委托函数构造顺序

int main()
{
    Sales_data date1("os9001-1",100,7000.0);
    cout<<"----------------------------"<<endl;
    Sales_data date2("os9001-1");
    cout<<"----------------------------"<<endl;
    Sales_data date3;
    cout<<"----------------------------"<<endl;
    std::string str="0s9002-1" ;
    Sales_data date4(str);
    cout<<"----------------------------"<<endl;
    Sales_data date5(std::cin);
    return 0;
}

附截图
image.png

7.42 基本模仿7.41

class Employee{
public:
    Employee(unsigned number,std::string name,std::string department )
    :number(number),name(name),department(department){}

    //employee(std::istream &is) {is>>name>>dartment>>age>>work_long;}
    Employee():Employee(0,"",""){}
    Employee(unsigned  n ): Employee(n,"",""){}
    Employee(std::istream &in)
    {
        in >>number>> name >> department  ;
    }



private:
    unsigned number;
    std::string name;
    std::string department;

};

7.43

class NoDefault{
  public :
    NoDefault(int i){}//1,NoDefault的构造函数中有一个int型的参数
};
class C{
  public :
    C():member(0){}//3,初始化时要用NoDefault中的构造函数去初始化
  private:
    NoDefault member;//2,C中有一个NoDefault 对象成员
    
}

7.44有问题
错误显示


image.png

就是说
NoDefault 没有默认构造函数,要实例化NoDefault 对象的时候要给它int的参数,这样申请十个对象的vector时实例化是有问题的
7.45
合法了,因为C中有构造函数,并且c中的构造函数中使用NoDefault 对象成员的时候给了它int参数,是合法的

其实7.44,7.45的根本症结在于
NoDefault类我们显式的定义了一个带int参数的构造函数,所以在进行实例化的时候我们也必有显式的给出实例化对象的int型参数,7.44错在于无法给出这个int型参数,7.45中因为是C的实例化,在c的实例化的时候给出了默认的int型参数,所以7.45是合法的

7.46
1,不需要,若是我们不提供一个构造函数,类会默认提供一个隐式的构造函数,叫默认构造函数
2,不一定,若是默认值都为空就是对的,但是我们显式定义默认的构造参数的时候,若是给出了默认值,那它的参数列表就不为空
3,不对,类一定会提供默认的构造函数,为了防止出现实例化出问题也得提供一个构造函数
4,默认构造函数是指xxx()的函数,若是我们没有显式的定义它,同时也没有定义其他带参数的构造函数,实例化的时候会生成相应类型的默认值,但是如果我们定义了其他的构造函数,实例化的时候则要看我们自己的选择。

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》读薄系列笔记全集。 目录 第I部分:C++基础 开始学习C++ 变量和基本类型 字...
    尤汐_Jennica阅读 5,518评论 1 42
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 1,445评论 0 8
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 18,291评论 1 40
  • C/C++输入输出流总结 前两天写C++实习作业,突然发现I/O是那么的陌生,打了好长时间的文件都没有打开,今天终...
    LuckTime阅读 967评论 0 6
  • 1、鸡脯肉洗净切成丁,放入容器,加入胡椒粉、鸡蛋、料酒、干淀粉搅匀腌制20分钟; 2、葱、姜、蒜切成片,干辣椒切成...
    卓越小深阅读 42评论 0 0