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
不是,并不是常量成员