第一章 引论-C++常识

来源:互联网 发布:java程序加载类的步骤 编辑:程序博客网 时间:2024/05/22 21:06

1.4 C++ 类

     在C++中类由成员构成。成员可以是数据,可以是函数,其中函数成为成员函数。类中的每一个实例都是一个对象。每一个对象包含类中指定的数据成员(除非这些数据成员是static)。如下图所示

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class IntCell
{
public:
    explicit IntCell(int initvalue=0);  /*所有的单参数的构造函数都必须使用explicit,以避免后台的类型转换。*/
    IntCell(const IntCell &rhs);   /*复制构造函数*/
    ~IntCell();                /*析构函数*/
    const IntCell & operator=(const IntCell &rhs); /*operator=函数*/

    int read() const;    /*常量成员函数*/
    void write(int x);
private:
    int *storevalue;
};

IntCell::IntCell(int initvalue)
{
 storevalue=new int(initvalue);
}

IntCell::IntCell(const IntCell &rhs)
{
    storevalue=new int(*rhs.storevalue);
}
IntCell::~IntCell()
{
 delete storevalue;
}

const IntCell &  IntCell::operator=(const IntCell &rhs)
{
 if(this!=&rhs)
 {
     *storevalue=*rhs.storevalue;
 }
 return *this;
}


int IntCell::read() const
{
 return *storevalue;
}
void IntCell::write(int x)
{
 *storevalue=x;
}

1、默认参数

    IntCell构造函数阐述了默认参数,定义了两个IntCell 构造函数。一个构造函数接受initialValue,另一个是零参数构造函数,后者隐藏。

2、初始化列表

    构造函数代码体前的代码。

3、explicit构造函数。

     所有的单参数的构造函数都必须是explicit的,以避免后台的类型转换。如下代码:

     IntCell obj;

     obj=37;

    C++拥有宽松的规则,通常,单参数构造函数定义了一个隐式类型转换,该转换创建了一个临时对象,从而使得赋值兼容。

     编译器尝试将obj=37;转换成Intcell temp=37;  obj=temp;

     注意临时对象的构造也可以通过使用单参数构造函数实现。使用explicit意味着单参数构造函数不能用来创建隐式临时对象。

4、常量成员函数

      访问函数一般是常量成员函数。修改函数。


1.5 C++ 基础

     1.5.1 指针

      指针变量是用来存储其他对象地址变量。主要用于声明、动态对象创建、垃圾收集及delete、指针的赋值和比较、访问对象成员。

    内存泄漏:当一个通过new来分配地址的对象不再引用时,该对象所占的内存不能释放(直到程序结束)。

    1.5.2 参数传递

     C++有三种传参方式,如:double avg(const vector<int> &arr,int n, bool &flag);

     这里 arr是vector<int> 类型,使用按常量引用调用来传递。n是int类型,通过按值调用来传递。flag 是bool类型,使用引址调用。

     1.5.3 引用变量

     用于传参。

     1.5.4 三大函数:析构函数、复制构造函数和operator=

 1、析构函数

     在一个对象超出其作用域或执行delete时,就调用析构函数。通常析构函数的唯一任务是释放使用对象时所占有的所有资源。

2、复制构造函数

    有一种特殊的构造函数,用于构造新的对象,被初始化为相同类型对象的一个副本,这就是复制构造函数。如:

Intcell b=c,或者Intcell b(c)。

3、operator=函数

    应用于两个已经构造的函数,用于复制。

4、重构这三大函数的主要原因

     采用默认函数,只能实现浅复制。主要问题出现在其数据成员是指针的类。

    默认的构造函数不对指针进行任何操作(一个好的理由就是释放这个指针旧必须删除自身)。默认的复制构造函数和operator=也都不复制指针所指向的对象,而是简单地复制指针的值,这样一来得到两个实例,他们包含的指针都指向同一个对象。这被称为浅复制。

      我们期望的是对整个对象克隆的深复制。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


IntCell::IntCell(int initvalue)  //构造函数
{
 storevalue=new int(initvalue);
}

IntCell::IntCell(const IntCell &rhs)  //复制构造函数
{
    storevalue=new int(*rhs.storevalue);
}
IntCell::~IntCell()  //析构函数
{
 delete storevalue;
}

const IntCell &  IntCell::operator=(const IntCell &rhs)  //operator= 函数
{
 if(this!=&rhs)
 {
     *storevalue=*rhs.storevalue;
 }
 return *this;
}
       浅复制带来的问题:指针被复制而不是指针所指向的对象被复制,其次一个不明显的问题是内存泄漏。b、c两个指针变量都需要释放。

 C++ Code 
1
2
3
4
5
6
IntCell b(1);
IntCell c(b);
cout << b.read() << "," << c.read() << endl;

c.write(2);
cout << b.read() << "," << c.read() << endl;

1.6 模板

      模板包括函数模板和类模板。

       函数对象的一个典型例子。

      注意,对象同时包含数据和成员函数,一个如传递参数一样传递函数的巧妙方法是:定义一个包含零个数据和一个成员函数的类,然后传递这个类的实例。从效果上看就是,通过将其放在对象中实现了函数的传递。该对象通常称为函数对象。具体代码实现如下:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename v1 , typename v2>
const v1 &findMax(const vector<v1> &a, v2 isLessThan)
{
    int MaxIndex = 0;
    for(int i = 0; i < a.size(); i++)
        if(isLessThan(a[MaxIndex], a[i]))
            MaxIndex = i;
    return a[MaxIndex];
}

class CaseInsensitiveCompare  //重载()操作符
{
public:
    bool operator() (const string &lhs, const string &rhs) const
    {
        return stricmp(lhs.c_str(), rhs.c_str()) < 0;
    }
};

1.7 使用矩阵

     

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//使用矩阵  使用向量的向量
template <typename Object>
class maxtrix
{
public:
    maxtrix(int rows, int cols): array(rows)
    {
        for(int i = 0; i < rows; i++)
        {
            array[i].resize(cols);
        }
    }
    const vector<Object> &operator[](int row) const
    {
        return array[row];
    }
    int numrows() const
    {
        return array.size();
    }
    int numcols() const
    {
        return numrows ? array[0].size() : 0;
    }


private:
    vector<vector<Object> >array;
};



0 0
原创粉丝点击