类设计的几点认识及设计一个自己的类String类

来源:互联网 发布:js parsefloat 精度 编辑:程序博客网 时间:2024/06/06 01:43

感觉现在的面试都很有意思,上来就问你C++中虚函数表 ,你了解吗,是怎么实现的?对最基本的类设计从来不问。甚至问你用C实现C++的多态。

其实,能否设计一个基本类,能体现对C++的类设计的掌握情况。(今年,中兴,和东软的笔试题中好像都有设计类的题, 但是也不能防止某些人背过)。



个人认为,一个好的类设计,应该是使类类型像我们熟知的基本类型一样使用,即使类像基本类型一样使用。

不考虑继承,不考虑多态,设计的类类型应该考虑一下几个方面:

1. 无参数的构造函数(default constructor): 当类无任何构造函数,编译器自动生成一个构造函数。

     但是,当声明其他参数的构造函数,编译器将不能生成default constructor。随之,而来的问题,你不能像基本类型那样声明变量;也不能声明该类类型的数组。

2. 拷贝构造函数( copy constructor):用一个对象初始化另一个对象。(仅此情形,无论函数参数的值传递,还是 return 值传递,都是此情形)。

                                                                初始化,则意味着另一个对象从未调用过构造函数,只是分配了内存。

3. 赋值操作符(assignment operator =):  对已初始化的对象的赋值。已初始化的对象即曾用调用过构造函数。


4. 析构函数(destructor): 析构函数,当对象过期(out of scope)时,对对象进行析构操作(防止内存泄露,或者资源泄露)。

                                               显式地调用析构函数 并未释放该类对象所占的内存,类对象的内存释放,是类的存储管理的一部分。

                                              对于支持多态的基类,其析构函数一定要为virtual,(尽管派生类的类名 不与基类的类名一样,但其可构成协变重写)。

5.delete/new(类的存储管理):首先要搞清楚几个概念:new operator与operator new的区别以及delete operator与 operator delete的区别。

     new operator:平时 new 一个对象的这个new就是new operator:其背后做哪些工作呢?

                              <1>调用operator new(这个是标准存储分配库函数,也可以在类设计时对其重写),分配该类对象的内存空间。

                              <2> 调用该类的构造函数, 完成类对象的初始化.(包括动态内存的分配,资源的分配等)。

     delete operator:同理 delete operator也在默默做着一些工作:

                              <1> 调用类的析构,函数完成类对象的去初始化,即(动态分配内存、资源的回收)防止内存、资源泄露。

                              <2> 调用 operator delete 回收该类对象的内存。

此外,对数组的内存的分配与回收的:operator array new 和operator  array delete;


对于不考虑类继承的String类的设计:如下:

1. 类的声明文件:MyString.h

#ifndef __MyString_h#define __MyString_h#include <iostream>#include <cstring>using namespace std;class MyString{    char *str;public:      MyString();  //default constructor;      ~MyString(); //default destructor;      MyString(const MyString & that); // copy constructor      MyString& operator=(const MyString &that); //assignment operator     MyString(const char *str); //转换 constructor    void print() {        cout << str << endl;        cout << endl;    }};#endif

2.类的实现文件: MyString.cpp

#include "MyString.h"//default constructorMyString:: MyString() : str(NULL) {        cout << "Constructor: MyString()" << endl;        str = new char[1];        str[0] = '\0';}//转换构造函数MyString::MyString(const char *str) {    cout << "Constructor: MyString(const char *)" << endl;    if(NULL == str) {        this->str = new char[1];        this->str[0] = '\0';    }else {        this->str = new char[strlen(str) + 1];        strcpy(this->str, str);    }}//copy constructorMyString::MyString(const MyString &that) {    cout << "Copy Constructor Mystring(const Mystring &that) " << endl;    str = new char[strlen(that.str) + 1];    strcpy(str, that.str);}// assignment operator =MyString& MyString::operator=(const MyString &that) {    cout << "assignment operator: operator=(const MyString &that)" << endl;    if(this != &that) {        char *tmp = new char[strlen(that.str) + 1];        strcpy(tmp, that.str);        delete [] str;        str = tmp;    }    return *this;}MyString::~MyString() {    cout << "Destructor: ~MyString()" << endl;    if(str) {        delete[] str;        str = NULL;    }}

3.测试文件:main.cpp

#include "MyString.h"int main(){    MyString s; //default constructor    s.print();    MyString ss("hello"); //转换构造函数 constructor    ss.print();    MyString sss = ss; // copy constructor 用一个对象初始另一个对象    sss.print();    MyString ssss(s); // copy constructor;    ssss = sss;       //assignment operator = : 给一个已初始化的对象赋值    ssss.print();    MyString sssss = "hello world"; // wrong, as explicit modified.    sssss.print();    return 0;}


另一个类实现:Clock


#include <iostream>using namespace std;class Clock{public:Clock(int hour, int minute, int second);Clock(const Clock &that); //复制构造函数Clock &operator=(const Clock &that);~Clock(); //析构函数void SetTime(int hour, int minute, int second);void ShowTime();private:int _hour;int _minute;int _second;};Clock::Clock(int hour, int minute, int second): _hour(hour), _minute(minute), _second(second) {cout << "constructor Clock(int, int, int)" << endl;}Clock::Clock(const Clock &c) { //复制构造函数cout << "copy constructor" << endl;SetTime(c._hour, c._minute, c._second);}Clock &Clock::operator=(const Clock &that) {cout << "in operator=(Clock &that) " << endl;if(this != &that) { //防止自我赋值//this->~Clock();SetTime(that._hour, that._minute, that._second);}return *this;}void Clock::SetTime(int hour, int minute, int second) {_hour = hour;_minute = minute;_second = second;}void Clock::ShowTime() {cout << _hour << ":" << _minute << ":" << _second << endl;}Clock::~Clock(){cout << "destructor: ~Clock()" << endl << endl;}Clock GetClock();int main(){Clock GetClock(); //声明函数Clock myClock1(1, 2, 3); //构造函数 Clock(int, int, int)myClock1.ShowTime();cout << endl << endl;Clock myClock2(myClock1); // copy constructor Clock(const Clock &c);myClock2.ShowTime();cout << endl << endl;Clock myClock3 = GetClock(); //copy constructor Clock(const Clock &c); 可能被优化。myClock3.ShowTime();cout << endl << endl;myClock3 = myClock2;        // assignment operator=(const Clock &that);myClock3.ShowTime();cout << endl << endl;myClock3 = GetClock();  //copy constructor && operator= () 。myClock3.ShowTime();cout << endl << endl;}Clock GetClock(){cout << "in Fuction: GetClock()" << endl;Clock tmpClock(5,6,7); //构造函数 Clock(int, int, int)return tmpClock;}




                         

                 

原创粉丝点击