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()的函数,若是我们没有显式的定义它,同时也没有定义其他带参数的构造函数,实例化的时候会生成相应类型的默认值,但是如果我们定义了其他的构造函数,实例化的时候则要看我们自己的选择。
网友评论