类设计的几点认识及设计一个自己的类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;}
- 类设计的几点认识及设计一个自己的类String类
- 设计一个string类
- c++ 基类设计 需要注意的几点
- 关于String类的几点说明
- 字符串类String的设计
- C++实现一个自己的string类
- 一个数据采集系统的设计及重要点
- C#之类的设计:点和三角形类的设计
- 正确使用String类的几点注意
- 正确使用String类的几点注意
- 正确使用String类的几点注意
- 正确使用String类的几点注意
- 正确使用String类应注意的几点
- 关于设计模式的几点思考
- SOA设计的几点思考
- 数据库设计原则的几点考虑
- 关于设计模式的几点误区
- 系统设计的几点经验
- android textview 中超出屏幕宽度的字符 省略号显示
- css如何在一个工具条中定义向左(或向右)靠的button
- android:屏幕自适应(转)
- Orace技术网开发人员日——云计算和大数据参加笔记
- BZOJ 1028(n小于100时的枚举)
- 类设计的几点认识及设计一个自己的类String类
- 整理struts2所有标签
- UIScrollView的使用大全
- ACM zoj 3533(伸展树实现)
- C语言中volatile的含义(原来这是区分C程序员和嵌入式系统程序员的最基本的问题)
- 第7贴:音调电路 电平指示
- jsp中一个路径导致的错误
- XML文件解析,未找到节点
- OpenCV 用cv::Mat显示OpenNI获得的Kinect深度图片