从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;    
}


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

相关文章推荐

struct位域,对齐以及union作为class需要注意的地方

一. struct对齐在c/c++中,struct结构体的大小不是简单的成员变量所占空间大小的累加,这里面涉及到变量对齐(alignment)的概念,由于计算机中内存的结构,使得cpu从某个特定边界的...

C++类中需要注意的地方

类的静态成员函数不允许声明为const,否则编译会报错。当类的非静态成员函数被声明为const, 表明这个非静态成员函数隐含传入的this指针为const指针,即指针指向的对象为常量, 在函数内部不允...

String.split需要注意的地方

在Java中经常会用到split这个函数完成字符串的切割,不过有些需要注意的地方,直接上代码:public class Test { public static void main(Strin...

2015 暑假多校训练---CRB and String(简单但有很多需要注意地方)

题目链接 http://acm.hust.edu.cn/vjudge/contest/131172#problem/BDescription CRB has two strings ss and ...

Primer plus C++ 第十一章 类和动态内存分配_反面理解String类(class and dynamic memory allocation)

/************************************************************************/ /* strngbad.h __ flawed(...

从c++转到Python需要注意的地方

下面的资料,会随着学习的不断深入,持续的更新。 内容没有能有效的组织,因为没一点是本人再学习的过程中,慢慢的总结出来的。等本篇文字足够长的时候,可能会考虑组织文件可读性更强的文字。   1. c...

C++使用localtime函数需要注意的地方

在处理时间时用到了localtime这个函数,将一个UTC时间转为本地时间: [cpp] #include time_t tmNow = time(NULL); tm *ptmNow = local...

c/c++指针精讲和需要注意的地方

讲的不够好 有些内容下次补充完整

C++运算符重载需要注意的地方

原文地址:http://www.2cto.com/kf/201208/151228.html 有时候自己写一个类,需要重载运算符,但对于一些操作符(如==、等),可以在类里写,也可以在类外写。那么 ...

C++运算符重载需要注意的地方

有时候自己写一个类,需要重载运算符,但对于一些操作符(如==、、>等),可以在类里写,也可以在类外写。那么 C++ 编译器会去怎么调用呢? 首先,我们知道,“重载” 机制可以允许多个函数有相...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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