从String类看写C++ class需要注意的地方

原创 2007年09月16日 02:34:00

 

 

// String.h的定义:
#include <string.h> //strlen, strcpy等C字符串处理函数
#include <iostream>

using namespace std;


class String
{
public:
    String(const char* p=NULL)      // 构造函数
    {
        if(p==NULL) // String str;  //将构造一个长度为0的空字符串""
        {
            data = new char[1];     // 构造对象的三种方式(指定实参的方式):
            *data = '/0';           // String s1("hello");          // 第1种,常用的,推荐的
            size = 0;               // String s2 = "hello";         // 第2种,只适用与单个实参。
        }                           // String s3 = String("hello"); // 第3种,很少见
        else
        {
            size = strlen(p);
            data = new char[size+1];    // 注意需要+1,存放'/0'
            strcpy(data,p);
        }
    };

    String(const String& str)       // 拷贝构造函数,如下构造String对象时会调用:
    {                               // String s1 = "hello";
        size = str.size;            // String s2(s1); // 调用拷贝构造函数
        data = new char[size+1];    // String s3 = s1;// 调用拷贝构造函数
        strcpy(data,str.data);      // String s4;
    };                              // s4 = s1; //不会调用拷贝构造函数,而是调用operator=

    String& operator = (const String& other)    // 赋值操作符
    {   // 如果省略,需要时,会调用缺省的operator=。但本类不能省略,因为存在char*的成员。     
        if(this != &other) // 注意自赋值!!
        {                           // 如果省略该operator=,以下代码将是灾难性的:
            delete[] data;          // String s1 = "hello";
            size = other.size;      // String s2;
            data = new char[size+1];// s2 = s1;//调用缺省的operator=,data指向同一片内存
            strcpy(data,other.data);// 如果也没有char*的operator=的话,以下代码也有同样问题
        }                           // String s1;
        return *this;               // s1 = "hello"; //先构造临时对象,再调用缺省的String的operator=
    };                              // 该问题,详细可以参考:EffectiveC++ item11

    String& operator = (const char* p) 
    {                               // char* 的operator=
        delete[] data;              // 在如下代码时会调用
        if(p==NULL)                 // String s1;
        {                           // s1 = "hello";
            data = new char[1];     // 如果没有该operator=,s1 = "hello"会先根据"hello"构造临时对象,
            *data = '/0';           // 然后再调用String的operator=(自定义或缺省的)赋值给s1
            size = 0;               // 可以用explicit关键字修饰const char*的构造函数禁止此隐式转换
        }                           // 但要注意下面这条语句是不会调用该operator=,而是调用构造函数:
        else                        // String s1 = "hello";
        {
            size = strlen(p);
            data = new char[size+1];
            strcpy(data,p);
        }
        return *this;               // 注意返回值为String&,为了链式表达,如:s2 = s1 = "hello";
    }

    bool operator == (const String& other)
    {
        if(this == &other)
        {
            return true;
        }
        else
        {
            return strcmp(data,other.data) == 0;
        }
    }

   
    ~String(void)
    {
        if(data != NULL)
        {
            delete[] data;      // 注意数组的delete形式!!!
        }
    };

    // operator<<重载,该操作符的重载必须定义为命名空间函数,不能定义为该类的成员函数。
    // 因为:只有在左left 操作数是该类类型的对象时才会考虑使用作为类成员的重载操作符。
    // 而<<左操作数是ostream,所以不能使用类成员函数。
    // 为了该非类成员函数能够访问String的私有成员,故在次声明为该类的友元函数。
    friend ostream& operator << (ostream& out, const String& str); 


private:
    char* data;
    int size;

};


// String.cpp的实现:
#include "./String.h"

// String的operator<<的定义。
ostream& operator << (ostream& out, const String& str)
{   // 因为已经声明了String的friend函数,故可以直接使用String的private成员data
    out<<str.data;  // 否则需要在String中定义一个public的函数获取数据  
    return out;    
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

关于重载的概念和使用时的注意事项

本文对重载的概念和一些基本的常见用法作了一些归纳,供读者参阅。
  • qq_38234015
  • qq_38234015
  • 2017年04月24日 11:43
  • 427

Eclipse中查看Java源代码的方法及一些注意事项

在Eclipse中我们可以通过同时按Ctrl键点击要查看的类或方法,就可以查看该类或方法的源代码了。但是,这是需要有前提的,那就是,我们有源代码,并且配置了Eclipse的正确的查找路径。 我们可以...
  • G_66_hero
  • G_66_hero
  • 2017年04月15日 13:53
  • 413

C++ 编写类文件的时候,需要注意的问题

原博文链接在我的官方网站,网址是:http://www.aobosir.com/blog/2017/02/07/cpp-cmake-aux_source_directory/一段时间不编写程序了,基本...
  • github_35160620
  • github_35160620
  • 2017年03月04日 03:54
  • 2348

C++_运算符重载的注意事项

1、重载操作符没必要一定是成员函数,还可以是友元函数。 2、重载操作符函数为成员函数主要是你需要操作类内部的成员, 必须是成员函数或友元函数才行。 3、至于由深浅拷贝的原因要使其成为成员...
  • u010003835
  • u010003835
  • 2015年09月06日 11:32
  • 1027

mysql查询注意事项

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。   2.应尽量避免在 where 子句中使用!=或   3.应尽量避免在 where 子句...
  • Z729685731
  • Z729685731
  • 2016年10月14日 14:43
  • 125

C语言需要注意的地方

今天看了一本C陷阱与指针的书,从中挑选了一些我自己平常不太注意的地方,或者有些是记不太清的东西,稍微整理了下有以下这些地方: 1:=与==是不同的,一个是赋值,一个是比较 2:&与&&是不同的,前...
  • chuhang_zhqr
  • chuhang_zhqr
  • 2016年01月27日 23:10
  • 497

从pascal转到c++的感受

从pascal转到c++,我这一个月下来,感受是这样的: 真心感觉pascal的语句更能让人理解 而且pascal还不用打头文件 不过我慢慢也发现了c++的优点:   1. 功能   功能上 ...
  • myc0_0
  • myc0_0
  • 2017年10月20日 10:02
  • 93

C++ 多线程注意事项

1.线程中调用对话框控件。 当线程还在调用对话框中的控件时,比如插入数据、删除数据、显示图片等。则会崩溃 2.线程绘制对话框 线程中绘制对话框,第一是会出现上面所说的,第二在低配置的电脑上会出现白...
  • sz76211822
  • sz76211822
  • 2016年09月19日 11:28
  • 491

Code Review的一些注意事项(英文版)

当你进行Code Review的时候,你能很快发现问题吗?你能保证不遗留问题吗?下面是个Check List, 在Code Review结束后看一遍,查漏补缺,有助于吹毛求疵。以前在外企写的,懒得翻译...
  • ffmpeg4976
  • ffmpeg4976
  • 2015年01月02日 12:02
  • 294

C++类中的内存对齐

对齐规则在没有#pragma pack宏的情况下:  1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成...
  • u010185700
  • u010185700
  • 2016年09月13日 14:47
  • 604
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从String类看写C++ class需要注意的地方
举报原因:
原因补充:

(最多只允许输入30个字)