class Screen {
public:
typedef string::size_type pos;
Screen() = default;
Screen(pos wightVal, pos heightVal):wight(wightVal), height(heightVal), contents(wightVal*heightVal, ' ') {
cout << contents << " " << wight << " " << height << endl;
}
Screen(pos wightVal, pos heightVal, char contents) :wight(wightVal), height(heightVal), contents(wightVal*heightVal,contents){
cout << contents << " " << wight << " " << height << endl;
}
private:
pos cursor = 0;
pos wight= 0, height = 0;
string contents;
};
7.25,对该题目的答案保有疑问,通过网上查询答案为大多数为不能,但个人觉得是可以的,并做了以下检验:
成功输出拷贝后的数据,(将两个参数的构造函数改为默认插入字符b而不是空格来方便查看结果)
翻阅书本在P239上写明是关于内存操作的拷贝和赋值才会有合成版本的问题,在P240页第一段也写明了"如果类包含vector或者string成员,则其拷贝,赋值和销毁的合成版本能够正常工作"
7.26:
在类外需要加上inline关键字,在类内定义的话将默认是内联函数
7.27
class Screen {
public:
typedef string::size_type pos;
Screen() = default;
Screen(pos wightVal, pos heightVal):wight(wightVal), height(heightVal), contents(wightVal*heightVal, ' ') {
}
Screen(pos wightVal, pos heightVal, char contents) :wight(wightVal), height(heightVal), contents(wightVal*heightVal,contents){
}
Screen& set(char);
Screen& move(pos r, pos col);
Screen& display(ostream& os);
int getWight()const { return wight; }
string getContents()const { return contents; }
int getHeight()const { return height; }
private:
pos cursor = 0;
pos wight= 0, height = 0;
string contents;
void do_displayer(ostream& os){
os << contents;
}
};
inline
Screen& Screen::set(char c){
contents[cursor] = c;
return *this;
}
inline
Screen& Screen::move(pos r, pos col){
cursor = wight * r +col;
return *this;
}
inline
Screen& Screen::display(ostream& os){
do_displayer(os);
return *this;
}
int main() {
Screen myScreen(5, 5, 'x');
myScreen.move(4,0).set('#').display(cout);
cout<<'\n';
myScreen.display(cout);
cout<<'\n';
for (;;);
return 0;
}
7.28
第一次改变就不是我们声明的myScreen,而每次操作函数后都会生成一个新的临时变量,我们只是对临时变量进行操作
第二次display输出的就是原来我们声明初未进行任何修改的的myScreen
7.29
7.30
优点,在新手阶段,对函数调用形参还是成员函数方便理解
熟悉之后,再使用this可能会导致程序的简洁程度下降
7.31:????
class Y {
X x;
};
class X {
Y* y;
};
7.32
using namespace std;
class Screen {
public:
typedef string::size_type pos;
friend class Window_mgr;
Screen() = default;
Screen(pos wightVal, pos heightVal):wight(wightVal), height(heightVal), contents(wightVal*heightVal, ' ') {
}
Screen(pos wightVal, pos heightVal, char contents) :wight(wightVal), height(heightVal), contents(wightVal*heightVal,contents){
}
Screen& set(char);
Screen& move(pos r, pos col);
Screen& display(ostream& os);
int getWight()const { return wight; }
string& getContents(){ return contents; }
int getHeight()const { return height; }
pos size()const;
private:
pos cursor = 0;
pos wight= 0, height = 0;
string contents;
void do_displayer(ostream& os){
os << contents;
}
};
Screen::pos Screen::size()const{
return height * wight;
}
class Window_mgr {
public:
typedef string::size_type ScreenIndex ;
void clear(ScreenIndex index);
private:
vector<Screen> screens{ Screen(24, 80, ' ') };
};
void Window_mgr::clear(ScreenIndex index){
Screen & s = screens[index];
s.getContents() = string(s.getWight()*s.getHeight(), ' ');
}
inline
Screen& Screen::set(char c){
contents[cursor] = c;
return *this;
}
inline
Screen& Screen::move(pos r, pos col){
cursor = wight * r +col;
return *this;
}
inline
Screen& Screen::display(ostream& os){
do_displayer(os);
return *this;
}
int main() {
for (;;);
return 0;
}
7.33:
Screen::pos Screen::size()const{
return height * wight;
}
7.34:
名字查找指包括成员函数出现之前的部分,所以,编译器会报错
7.35
存在作用域判断错误:
修改后如下:
typedef string Type;
Type initVal(){}
class Exercise {
public:
typedef double Type;
Type setVal(Type);
Type initVal(){ val = 1; return val;}
private:
int val;
};
Exercise::Type Exercise::setVal(Exercise::Type param){
val = param + Exercise::initVal();
return val;
}
7.36:
根据编译器不同,可能有不同结果,所以不要用成员变量去列表初始化另一个成员变量
作如下更改:
struct X {
X(int i, int j):base(i),rem(i%j){}
int rem,base;
};
7.37:first_item使用了 Sales_data(std::istream &is)根据输入流初始化
剩余都是 Sales_data(std::string s = "") 初始化,next 默认值为"", last默认值为9-999-99999-9
7.38
struct X {
X(istream& is = cin){is>>s;}
string s;
};
7.39
当然不合法,两个构造函数都会匹配构造,产生二义性
7.40:略
7.41:委托构造函数如被委托构造函数体内有代码,则先执行这些代码
具体Sales_data 略
7.42:同上,略
7.43
struct NoDefault {
NoDefault(int i):intValue(i){};
int intValue;
};
struct C { C(){}; NoDefault no = NoDefault(5);};
struct C {
C(NoDefault n = 5): no(n){};
NoDefault no ;
};
7.44:
不合法,没有默认构造参数
7.45
合法,虽然NoDefault没有默认构造函数,但是我们给C配置了默认构造函数
7.46
a.不正确,如果没有构造函数,系统会自动生成一个合成构造函数
b.不正确,默认构造函数可以有形参,只需带上默认实参即可
c.不正确,会导致后续使用时不便如作他类成员变量
d.正确
7.47:
优点:都不能隐式初始化
缺点:必须显示初始化
7.48
如果不是explicit,全可通过编译
如是,也全可通过编译
7.49
a,传入一个临时变量Sales_data
b.传入Sales_data引用
c.传入Sales_data常量引用,不能修改传入的Sales_data变量的值
7.50
可加可不加
7.51
可以防止意义不明
x(vector<int>)
如果不是explicit
x(10)就产生歧义
7.52:
不能携带默认初始值
修改后如下
struct Sales_data {
string bookNo;
unsigned units_sold;
double revenue;
};
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_id(bool b) { hw = b; }
void set_hw(bool b) { io = b; }
void set_other(bool b) { other = b; }
private:
bool hw;
bool io;
bool other;
};
7.54
不该吧,成员变量都不是const或者constexpr的
7.55
不是,并不是常量成员