原创作者: shi5jin
阅读:2658次
评论:0条
更新时间:2011-05-26
1.3 C++的设计
tips: "If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would detroy civilization." -- Gerald Weinberg
--------------------------------
“一个设计良好的用户自定义类型与一个内部类型之间的差异仅仅在于其定义的方式,而不在其使用的方式”[1]
这一句是stroustrup关于类设计的一句忠告。我觉得是一个设计风格的问题,也挺重要的。
首先说说“定义”。在C++中有几个相互关联的术语:“声明”(declaration)、“定义”(definition)和“实现”(implement)。初次学习C/C++的时候,我总是把他们三个混为一谈,或者说没有想去认真区别一下彼此。看过好多书之后发现,这点其实蛮重要的。
也就是说,声明一般仅仅为两项内容:名字(变量),以及名字的类型(当然一般还需要一个逗号,或分号)。例如:
cpp 代码
- int intVar;
- double yourCash, myCash;
- class Student;
- std::string studentName;
- int intMax(int, int);
而向如下的样式则不能称之为“声明”,而是“声明”+“定义”:
cpp 代码
- int intVar = 0;
- double yourCash = 0.0, myCash = 10e+10;
- class myClass {}; //an empty class;
- std::string studentName(“”);
u 定义(或对内置类型也可叫初始化):一个语句(块),它为程序中的一个类型(或变量)规定了其内部框架(或值)。例如:
cpp 代码
- int intVar; //declaration;
- intVar = 3; //definition;
- //class definition;
- class Student {
- int _studentNo;
- char _gender;
- std::string _birth;
- public:
- int number(void) const;
- char gender(void) const;
- std::string birth(void) const;
- };
- //a function definition/implement;
- int intMax(int a, int b) {
- return (a > b ? a : b);
- }
u 实现:主要针对类成员以及函数而言,即用具体算法实现成员、函数既定的功能。例如:
cpp 代码
- int
- Student::number(void) const {
- return _studentNo;
- }
通过上面的例子,我们已经可以看出,一个内置的类型和一个用户自定义的类型(class类)的定义的确不同。为了实现自定义类型所期望表达的类型内涵,我们必须给出需要的数据成员和用户接口[4]。但内置类型则不用,这是内置定义好了的。我们所要关心的是:为保持程序整体风格的一致,通过定义合适的用户接口,使用户在使用这些接口时,感觉就像使用一个内置类型一样。这将大大降低使用及维护成本。
例如我们想有一个用于数学、工程计算的Matrix类。当我们设计的该类的时候,我们就应该提供与STL相一致的接口、即功能,如我们可以这样声明、使用一个Matrix类:
cpp 代码
- using namespace gavin::math;
- Matrix matrix1(3, 5), matrix(5,3);
- matrix[0][0] = 3, matrix1[0][1] = 2;
- //…初始化matrix1和matrix2;
- Matrix result( matrix1 * matrix2 );
- cout << “We can print out the result: “ << result << endl;
- cout << “after multiply with 3 is: “ << 3*result << endl;
- cout << “And we can plus them: “ << matrix1 + matrix2 << endl;
- cout << “Sure can minus: “ << matrix1 – matrix2 << endl;
- cout << “Even get a negative: “ << -matrix2 << endl;
- cout << “Get the Matrix’s size: “ << matrix2.size() << endl;
- Matrix::iterator iter = result.begin(),
- iterEnd = result.end();
- for(; iter != iterEnd; ++iter) {
- cout << *iter << endl;
- }
我们所编写、自定义的类型,在使用上不仅要有与标准STL相同的接口名称,而且更主要的是要提供与STL接口相同的语义--相同的接口名称就应该实现相同或起码也是相近、不冲突的功能。而不应该采用C或其他语言的惯例,用一个函数去实现类似的功能。例如以下的用法是可以避免的:
cpp 代码
- printMatrix(matrix1); printMatrix(matrix2);
- matrixPlus(matrix1, matrix2);
假如你有些实践经验,那么采取标准STL风格的自定义类型的好处是显而易见的。无论是使用,还是后期的维护。
评论 共 0 条 请登录后发表评论