练习7.2
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
units_sold +=rhs.units_sold;
revenue +=rhs.revenue;
return *this;
}
std::string isbn()const
{
return bookNo;
}
练习7.3
Sales_Data total;
if(read(cin,total))
{
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.4
class Person
{
string name;
string addres;
};
练习7.5
class Person
{
string name;
string addres;
string getName()
{
return name;
}
string getAddres()
{
return addres'
}
};
答:是不是const都可以,函数没有实参传入。
练习7.6
Sales_data add(const Sales_data &lhs,const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
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;
}
练习7.7
Sales_Data total;
if(read(cin,total))
{
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.8
答:因为read中需要修改实参的值,而print不需要
练习7.9
class Person
{
string name;
string addres;
string getName()
{
return name;
}
string getAddres()
{
return addres'
}
istream &read(istream &is,Peraon &p)
{
is>>p.name>>p.addres
return is;
}
ostream &print(ostream &os,const Person &p)
{
os<<p.name<<" "<<p.addres;
return os;
}
};
练习7.10
答:判断返回的istream对象 是否正确。
关于Sales_data类的题目lz在这里就不写了,感兴趣的可以去阅读原书
练习7.15
class Person
{
string name;
string addres;
string getName()
{
return name;
}
string getAddres()
{
return addres'
}
istream &read(istream &is,Peraon &p)
{
is>>p.name>>p.addres
return is;
}
ostream &print(ostream &os,const Person &p)
{
os<<p.name<<" "<<p.addres;
return os;
}
Person(){}
Person(string n,string a):name(n),addres(a){}
};
练习7.16
答:没有,给用户提供的接口应该定义在public后,而类的数据成员应该定义在private后。
练习7.17
答:默认情况下,struct中的成员是public的,而class是private的
练习7.18
答:将类的接口和定义分离,把类的数据成员进行隐藏。
练习7.19
答:name和addres为private,其余的为public。
练习7.20
答:友元在想要访问类的私有成员时有用,弊端是可能会破坏类的封装。
练习7.22
class Person
{
public:
string getName()
{
return name;
}
string getAddres()
{
return addres'
}
istream &read(istream &is,Peraon &p)
{
is>>p.name>>p.addres
return is;
}
ostream &print(ostream &os,const Person &p)
{
os<<p.name<<" "<<p.addres;
return os;
}
Person(){}
Person(string n,string a):name(n),addres(a){}
private:
string name;
string addres;
};
练习7.23
class Screen
{
public:
typedef std::string::size_type pos;
private:
pos cursor = 0;
pos height = 0,width = 0;
string contents;
};
练习7.24
class Screen
{
public:
typedef std::string::size_type pos;
Screen(){}
Screen(pos w,pos h):width(w),height(h)
{
contents = " ";
}
Screen(pos w,pos h,char s):width(w),height(h),contents(s){}
private:
pos cursor = 0;
pos height = 0,width = 0;
string contents;
};
练习7.25
答:可以,Screen类没有需要动态分配内存的成员
练习7.27`
class Screen
{
public:
typedef std::string::size_type pos;
Screen(){}
Screen(pos w,pos h):width(w),height(h)
{
contents = " ";
}
Screen(pos w,pos h,char s):width(w),height(h),contents(s){}
Screen &move(pos r,pos c)
{
pos row = r*width;
cursor = row+c;
return *this;
}
Screen &set(char c)
{
contents[cursor] = c;
return *this;
}
Screen &display(ostream &os)
{
os<<contents;
return *this;
}
private:
pos cursor = 0;
pos height = 0,width = 0;
string contents;
};
练习7.28
答:第二条语句会出现问题
练习7.29
class Screen
{
public:
typedef std::string::size_type pos;
Screen(){}
Screen(pos w,pos h):width(w),height(h)
{
contents = " ";
}
Screen(pos w,pos h,char s):width(w),height(h),contents(s){}
Screen move(pos r,pos c)
{
pos row = r*width;
cursor = row+c;
return *this;
}
Screen set(char c)
{
contents[cursor] = c;
return *this;
}
Screen display(ostream &os)
{
os<<contents;
return *this;
}
private:
pos cursor = 0;
pos height = 0,width = 0;
string contents;
};
练习7.30
答:使用this指针会使程序过于繁琐,但是也可以使程序更加明了、
练习7.31
class Y;
class X
{
Y* pt;
};
class Y
{
X a;
};
练习7.32
class Screen
{
friend void Window_mgr::clear(ScreenIndex);
}
练习7.33
应该为:
Screen::pos Screen::size()const
{
return height*width;
}
练习7.34
答:前面使用pos的地方会报错
练习7.35
答:存在错误,在前面定义过的类型别名,在类内不能再重新定义
练习7.36
答:将base定义在rem前即可
练习7.37
略
练习7.38
Sales_data(istream &is = cin){}
练习7.39
答:不合法,函数调用时会产生二义性
练习7.40
class Tree
{
public:
Tree(){};
Tree(double h,double w):height(h),width(w){}
Tree(double h,double w,string n):height(h),width(w),name(n){}
private:
double height;
double width;
string name = " ";
};
练习7.41
略
练习7.42
class Tree
{
public:
Tree(){};
Tree(double h,double w,string n):height(h),width(w),name(n){}
Tree(double h,double w):Tree(h,w," "){}
private:
double height;
double width;
string name = " ";
};
练习7.43
class C
{
public:
C():NoDefault(0){}
private:
NoDefault n;
};
练习7.44
答:不合适,编译器将10当成是容器的大小,但NoDefault没有默认构造函数
练习7.45
答:合法,因为C有默认构造函数
练习7.46
答:a可以不提供构造函数,编译器会自动合成;c可以提供默认构造函数
练习7.47
答:不应该,这样可以转换类型
练习7.48
答:两条语句结果相同,都是将对象初始化为“9-999-99999-9”,声明为explicit无影响
练习7.49
答:ab相同,c应该将s初始化
练习7.50
class Person
{
public:
string getName()
{
return name;
}
string getAddres()
{
return addres'
}
istream &read(istream &is,Peraon &p)
{
is>>p.name>>p.addres
return is;
}
ostream &print(ostream &os,const Person &p)
{
os<<p.name<<" "<<p.addres;
return os;
}
Person(){}
Person(string n,string a):name(n),addres(a){}
private:
string name;
string addres;
};
答:没有需要声明为explicit的构造函数
练习7.51
答:vector中怕发生隐式的类类型转换
练习7.52
略
练习7.53
class Debug
{
public:
constexpr Debug(bool b = true):hw(b),io(b),other(b){}
constexpr Debug(bool h,bool i,bool o):hw(h),io(i),other(o){}
constexpr bool any(){return hw||io||other;}
void set_io(bool b){io = b;}
void set_hw(bool b){hw = b;}
void set_other(bool b){other = b;}
private:
bool hw;
bool io;
bool other;
};
练习7.54
答:不能,因为set_函数没有返回值,所以不能声明成constexpr
练习7.55
答:不是。string不属于字面值类型
练习7.56
答:静态成员不属于单独的一个对象,存在于任何对象之外
练习7.57
class Account
{
publid:
void calculate(){amount+=amount*interestRate;}
static double rate(){return interestRate;}
static void rate(double);
private:
std::string owner;
double amount;
static double interestRate;
static double initRate();
};
练习7.58
答:rate的定义错误,不能在类内提供初始值