通过一个C++类复习一些技术

生活在希望中的人,没有音乐照样跳舞!

虽然CSDN取消了博客发到首页功能,但是博客还会继续。孤芳自赏,自我分享。

下面我将通过一段代码来回顾一下C++中的类,其中包括的知识点都会进行注释讲解。
首先声明类 string.h文件,先上代码。

#ifndef STRING_H_
#define STRING_H_
#include <iostream>
using std::ostream;
using std::istream;
class String
{
private:
    char *str;
    int len;
    static int num_strings;//声明静态
    static const int CINLIM = 80;//声明静态并进行初始化
public:
    String(const char* s);//构造函数
    String();//默认构造函数
    String(const String &);//复制构造函数
    ~String();//析构函数
    int length()const {return len;}//内联函数,const后置
    String & operator=(const String &);//重载赋值运算符
    String & operator=(const char* );//重载赋值运算符
    String operator+(const String &)const;//重载运算符不能返回类的引用
    char & operator[](int i);//使用括号方法访问字符
    const char & operator[](int i) const;//可以根据const,进行重载
    friend bool operator<(const String &st1, const String &st2);//友元函数
    friend bool operator>(const String &st1, const String &st2);//友元函数
    friend bool operator==(const String &st1, const String &st2);//友元函数
    friend ostream & operator<<(ostream & os, const String &st);//友元函数
    friend istream & perator>>(istream & is, String & st);//友元函数
    static int HowMany();//静态成员函数
};
#endif

1.首先类的声明使用了#ifndef #define…#endif,具体作用可以参见博客《你所不知道的事儿–#ifndef #endif不能防止编译器将文件包含两次》。归根到底一句话,此作用就是让编译器忽略除第一次包含之外的所有内容。

2.在类中声明了静态变量

static int num_strings;//声明静态
static const int CINLIM = 80;//声明静态并进行初始化

静态类成员的特点就是无论创建多少对象,程序都只创建一个静态类变量副本。之所以不能在类里写static int num_strings=10;,原因就是在于此句描述了如何分配内存,但并不分配内存。可以使用作用域运算符进行初始化,但是没有关键字static。
但是如果使用了const修饰static,则可以在类声明中初始化。

3.复制构造函数
复制构造函数用于将一个对象复制到新创建的对象中。以下四种声明都将调用复制构造函数:

String ditto(motto);
String metoo = motoo;
String also = String(motto);
String * pString = new String(motto);

显示的定义一个构造函数来进行深复制:

String::String(const String & st)
{
    num_strings++;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
}

4.内联函数
内联函数在函数声明前加上关键字inline,在函数定义前加上关键字inline,通俗的讲,内联函数就是以空间换时间。
定义位于类声明中的函数都将自动成为内联函数。因此int length()const {return len;}为内联函数。

5.const后置
有如下的类和成员函数:

class Stock
{
public:
    void show()
    {}
};

现在执行代码:

cosnt Stock land = Stock("shit");
land.show();

对于当前的C++来说,编译器是拒绝第二行的。因此show函数无法保证调用对象不被修改。但是show又没有任何返回函数,所以C++解决方法是const关键字放在函数的括号后面。即上述代码所示。

6.重载赋值运算符
由于目标对象可能引用了以前分配的数据,所以函数应使用delete[]来释放这些数据;
函数应当避免将对象赋给自身;否则,给对象重新复制前,释放内存操作可能删除对象的内容;
函数返回一个指向调用对象的引用。

String & String::operator=(const String & st)
{
    if(this == &st)
        return *this;
    delete [] str;
    len = st.len;
    str = new char[len+1];
    std::strcpy(str, st.str);
    return *this;
}

7.重载的算术运算符不能返回引用
如果被返回的对象是被调用函数中的局部变量,则不应该按引用的方式返回它。因此在被调用函数执行完毕时,局部对象将调用其析构函数。通过被重载的算术运算符属于这一类。

8.使用中括号表示法访问字符
之间的博客中讲过,C++将区分常量和非常量的特征表。所以程序中提供了两个版本。

9.友元函数
C++提供了另一种形式的访问权限:友元。友元有三种:
友元函数
友元类
友元成员函数
可以通过让函数成为类的友元,可以赋予该函数与成员函数相同的访问权限。
创建友元的第一步是将其原型放在类声明中,并加上关键字friend
第二步是编写函数定义。因此不是成员函数,所以不要使用类::限定符,并且不要在定义中使用关
键字friend。
例如友元声明如下:

friend bool operator<(const String &st1, const String &st2);//友元函数

实现如下:

bool operator<(const String &st1, const String &st2)
{
    return st2
}

10.静态成员函数
文章《浅析C++中的static》中对静态进行了详解,文章《浅析C++中的static(一些补充)》对静态进行了进一步补充。
静态成员函数不能通过对象调用,不能使用this指针;可以访问静态成员,但是不能访问其他成员。例如上述代码中,静态方法HowMany()可以访问静态成员num_string,但不能访问str和len。

你可能感兴趣的:(Class)