标签:
类是 C++ 中最重要的特征。C++ 语言的早期版本被命名为“带类的 C(Cwith Classes)”,以强调类机制的中心作用。随着语言的演变,创建类的配套支持也在不断增加。语言设计的主要目标也变成提供这样一些特性:允许程序定义自己的类型,它们用起来与内置类型一样容易和直观。
类的定义和声明
隐含的this指针
构造函数
static类成员
一个实例
为了增进读者对上述文字的理解,这里给出一个实例,源自《C++ Primer》习题12.13:扩展Screen类以包含move、set和display操作通过执行如下表达式来测试类:
// 将光标移至指定位置,设置字符并显示屏幕内容
myScreen.move(4,0).set(‘#‘).display(cout);
答案如下:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Screen { 7 public: 8 typedef string::size_type index; 9 char get() const { return contents[cursor]; } 10 inline char get(index ht, index wd) const; 11 index get_cursor() const; 12 Screen(index hght, index wdth, const string &cntnts); 13 14 // 增加三个成员函数 15 Screen& move(index r, index c); 16 Screen& set(char); 17 Screen& display(ostream &os); 18 19 private: 20 std::string contents; 21 index cursor; 22 index height, width; 23 }; 24 25 Screen::Screen(index hght, index wdth, const string &cntnts) : 26 contents(cntnts), cursor(0), height(hght), width(wdth) { } 27 28 char Screen::get(index r, index c) const 29 { 30 index row = r * width; 31 return contents[row + c]; 32 } 33 34 inline Screen::index Screen::get_cursor() const 35 { 36 return cursor; 37 } 38 39 // 增加的三个成员函数的定义 40 Screen& Screen::set(char c) 41 { 42 contents[cursor] = c; 43 return *this; 44 } 45 46 Screen& Screen::move(index r, index c) 47 { 48 index row = r * width; 49 cursor = row + c; 50 return *this; 51 } 52 53 Screen& Screen::display(ostream &os) 54 { 55 os << contents; 56 return *this; 57 } 58 59 int main() 60 { 61 // 根据屏幕的高度、宽度和内容的值来创建 62 Screen Screen myScreen(5, 6, "aaaaa\naaaaa\naaaaa\naaaaa\naaaaa\n"); 63 64 // 将光标移至指定位置,设置字符并显示屏幕内容 65 myScreen.move(4, 0).set(‘#‘).display(cout); 66 67 return 0; 68 }
这个解决方法已满足了题目提出的要求,但存在一些缺陷:
(1) 创建Screen对象时必须给出表示整个屏幕内容的字符串,即使有些位置上没有内容。
(2) 显示的屏幕内容没有恰当地分行,而是连续显示,因此(4,0)位置上的‘#‘,在实际显示时 不一定正好在屏幕的(4,0)位置,显示效果较差。
(3) 如果创建的Screen对象是一个const对象,则不能使用display函数进行显示(因为const对 象只能使用const成员)。
(4) 如果move操作的目的位置超出了屏幕的边界,会出现运行时错误。
要解决第一个缺陷,可以如下修改构造函数:
1 Screen::Screen(index hght, index wdth, const string &cntnts = " "): cursor(0), height(hght), width(wdth) 2 { 3 // 将整个屏幕内容置为空格 4 contents.assign(hght*wdth, ‘ ‘); 5 // 用形参string对象的内容设置屏幕的相应字符 6 if (cntnts.size() != 0) 7 contents.replace(0, cntnts.size(), cntnts); 8 }
要解决第二个缺陷,可以如下修改display函数:
1 Screen& Screen::display(ostream &os) 2 { 3 string::size_type index = 0; 4 while (index != contents.size()) 5 { 6 os << contents[index]; 7 if ((index+1) % width == 0) 8 { 9 os << ‘\n‘; 10 } 11 ++index; 12 } 13 return *this; 14 }
要解决第三个缺陷,可以在Screen类定义体中增加如下函数声明: const Screen& display(ostream &os) const; 声明display函数的一个重载版本,供 const对象使用。
要解决第四个缺陷,可以如下修改move函数:
1 Screen& Screen::move(index r, index c) 2 { 3 // 行、列号均从0开始 4 if (r >= height c >= width) 5 { 6 cerr << "invalid row or column" << endl; 7 throw EXIT_FAILURE; 8 } 9 10 index row = r * width; 11 cursor = row + c; 12 return *this; 13 }
经过如上述几处修改,整个程序的健壮性,鲁棒性都得到了改善。全部代码如下:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Screen { 7 public: 8 typedef string::size_type index; 9 char get() const { return contents[cursor]; } 10 inline char get(index ht, index wd) const; 11 index get_cursor() const; 12 13 Screen(index hght, index wdth, const string &cntnts); 14 15 Screen& move(index r, index c); 16 Screen& set(char); 17 Screen& display(ostream &os); 18 const Screen& display(ostream &os) const; 19 20 private: 21 std::string contents; 22 index cursor; 23 index height, width; 24 }; 25 26 Screen::Screen(index hght, index wdth, const string &cntnts = "1"): 27 cursor(0), height(hght), width(wdth) 28 { 29 contents.assign(hght*wdth, ‘1‘); 30 31 if (cntnts.size() != 0) 32 contents.replace(0, cntnts.size(), cntnts); 33 } 34 35 36 char Screen::get(index r, index c) const 37 { 38 index row = r * width; 39 return contents[row + c]; 40 } 41 42 inline Screen::index Screen::get_cursor() const 43 { 44 return cursor; 45 } 46 47 Screen& Screen::set(char c) 48 { 49 contents[cursor] = c; 50 return *this; 51 } 52 53 Screen& Screen::move(index r, index c) 54 { 55 if (r >= height || c >= width) 56 { 57 cerr << "invalid row or column" << endl; 58 throw EXIT_FAILURE; 59 } 60 61 index row = r * width; 62 cursor = row + c; 63 64 return *this; 65 } 66 67 Screen& Screen::display(ostream &os) 68 { 69 string::size_type index = 0; 70 71 while (index != contents.size()) 72 { 73 os << contents[index]; 74 if ((index + 1) % width == 0) 75 { 76 os << ‘\n‘; 77 } 78 ++index; 79 } 80 return *this; 81 } 82 83 const Screen& Screen::display(ostream &os) const 84 { 85 string::size_type index = 0; 86 87 while (index != contents.size()) 88 { 89 os << contents[index]; 90 if ((index + 1) % width == 0) 91 { 92 os << ‘\n‘; 93 } 94 ++index; 95 } 96 return *this; 97 } 98 99 int main() 100 { 101 Screen myScreen(10,30); 102 //Screen myScreen(5, 6, "aaaaa\naaaaa\naaaaa\naaaaa\naaaaa\n"); 103 myScreen.move(4, 0).set(‘#‘).display(cout); 104 105 system("pause"); 106 107 return 0; 108 }
标签:
原文地址:http://www.cnblogs.com/huashu/p/4292672.html