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

感觉现在的面试都很有意思,上来就问你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 constructor
MyString:: 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 constructor
MyString::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;
}




                         

                 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值