Androider学C/C++—(8)动态内存,模板,异常处理

动态内存

基本概念

了解动态内存在 C++ 中是如何工作的是成为一名合格的 C++ 程序员必不可少的。C++ 程序中的内存分为两个部分:

栈:在函数内部声明的所有变量都将占用栈内存。
堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。

new 和 delete 运算符

new 运算符:
给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。

delete 运算符:
如果您不再需要动态分配的内存空间,删除之前由 new 运算符分配的内存。
在任何时候,当您觉得某个已经动态分配内存的变量不再需要使用时,您可以使用 delete 操作符释放它所占用的内存,如下所示:

delete pvalue;        // 释放 pvalue 所指向的内存

Code

本例代码,显示用new关键字动态分配了一下内存并且赋值,然后再判断了一下分配的内存地址是否为0,为0则表示oom,最后再delete并释放内存。


    #include <iostream>
    using namespace std;

    int main()
    {
        //------动态分配内存(实际上三行代码实现了一行代码的功能:double pvalue = 11.99;)----------
        double* pvalue = NULL; // 初始化为 null 的指针
        pvalue = new double;   // 为变量请求内存
        cout << "pvalue address: " << pvalue << endl;

        *pvalue = 11.99;     // 在分配的地址赋值
        cout << "赋值之后 Value of pvalue : " << *pvalue << endl;

        //------ 判断分配的地址是否为空 ----------
        double* pvalueif = NULL;


        //分析:
        //if(0038D3A0) ==> true  ,!true == false,则正常
        //若是if(0) == > false , !false == true ,那么则oom
        if (!(pvalueif = new double))
        {
            cout << "error: out of memory." << endl;
            exit(1);
        }
        else if (pvalueif = new double) {
            cout << "yes: 正常" << endl;
        }

        delete pvalue;         // 释放内存


        getchar();
        return 0;
    }

输出:

pvalue address: 0048D3A0
赋值之后 Value of pvalue : 11.99
yes: 正常

关于malloc()

malloc() 函数在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量不要使用 malloc() 函数。new 与 malloc() 函数相比,其主要的优点是,new 不只是分配了内存,它还创建了对象。

数组的动态内存分配

1.创建一维就是int * array;,二维就是int ** array,三维就是int *** array;
2.本例代码流程是,定义,开辟空间,赋值,打印。

一维


    //一维数组
    void one_dimmision() {

        //int[3] array = { 1,2,3 };

        int * array;
        int i = 3;

        //申请内存
        array = new int[i];

        //赋值
        for (int o = 0; o < i; o++)
        {
            array[o] = o;
        }

        //打印
        //int size = sizeof(array) / sizeof(array[0]);//动态数组不能用这种方式获取其长度

        //打印
        for (int i = 0; i < 3; i++)
        {
            cout << array[i] << ",";
        }


        //删除该数组内存
        delete[]array;

    }

二维

    //二维数组
    void two_dimmision() {
        int ** array;//二维数组指针,二维就是2个*
        int i = 3,j=4;//3行4列
        array = new int*[i];

        //开辟内存
        for (int o = 0; o < i; o++){
            array[o] = new int[j];//数组每个元素又是一个数组
        }

        //赋值 
        for (int m = 0; m < i; m++)
        {
            for (int n = 0; n < j;n++) {
                array[m][n] = 10 * m + n;

                //打印
                if (n == j -1) {
                    cout << array[m][n] << "," << endl;
                }
                else {
                    cout << array[m][n] << ",";
                }
            }
        }



        //删除
        for (int o = 0; o < i; o++)
        {
            delete [] array[o];//delete 类型 元素
        }

    }

输出:


    //0, 1, 2, 3,
    //10, 11, 12, 13,
    //20, 21, 22, 23,

三维


    //三维数组
    void threee_dimmision() {
        int *** array;
        int i = 3, j=4, k=5;
        array = new int **[i];

        //开辟内存 1维
        for (int o = 0; o < i; o++)
        {
            array[o] = new int *[j];//数组每个元素又是一个二维数组
        }

        //开辟内存 2维
        for (int m = 0; m < i; m++)
        {


            for (int n = 0; n < j;n++ ) {
                array[m][n] = new int[k];//开辟内存三维,数组每个元素又是一个一维数组

                //赋值
                for (int o = 0; o < k; o++)
                {
                    array[m][n][o] = 100 * m + (10 * n) + o;

                    //打印

                    //删除该数组内存
                    //delete[] array[m];


                    if (o == k - 1) {
                        cout << array[m][n][o] << "," << endl;
                    }
                    else {
                        cout << array[m][n][o] << ",";
                    }
                }
                cout << endl;
            }
            cout << endl;
        }

    }

输出:

                //20, 21, 22, 23, 24,

                //30, 31, 32, 33, 34,

                //100, 101, 102, 103, 104,

                //110, 111, 112, 113, 114,

                //120, 121, 122, 123, 124,

                //130, 131, 132, 133, 134,


                //200, 201, 202, 203, 204,

                //210, 211, 212, 213, 214,

                //220, 221, 222, 223, 224,

                //230, 231, 232, 233, 234,

对象数组的动态内存分配

注意这儿是对象数组:
Box* myBoxArray = new Box[4];

另外注意:
//Box myBoxArray = new Box; //错误写法


    #include <iostream>
    using namespace std;

    class Box
    {
    public:
        Box() {
            cout << "调用构造函数!" << endl;
        }
        ~Box() {
            cout << "调用析构函数!" << endl;
        }
    };

    int main()
    {
        Box* myBoxArray = new Box[4];

        //Box myBoxArray = new Box;  //错误写法

        delete[] myBoxArray; // 删除数组
        return 0;
    }

模板

模板就是泛型。分为模板方法,模板类,我个人比较习惯称其为泛型方法,泛型类。

泛型方法


    #include <iostream>
    #include <string>

    using namespace std;

    template <typename T>
    T const& Max(T const& a, T const& b)
    {
        return a < b ? b : a;
    }

    int main()
    {

        int i = 39;
        int j = 20;
        cout << "Max(i, j): " << Max(i, j) << endl;

        double f1 = 13.5;
        double f2 = 20.7;
        cout << "Max(f1, f2): " << Max(f1, f2) << endl;

        string s1 = "Hello";
        string s2 = "World";
        cout << "Max(s1, s2): " << Max(s1, s2) << endl;

        getchar();

        return 0;
    }

核心代码


    template <typename T>//泛型声明
    T const& Max(T const& a, T const& b)
    {
        return a < b ? b : a;
    }

泛型类


    #include <iostream>
    #include <string>

    using namespace std;

    template <class T>
    class A {

        public:
            void sayHello(T const&);
            T get();

    };

    template <class T>
    void A<T> :: sayHello(T const& t){
        cout << "say :" << t << endl;
    }

    template <class T>
    T A<T>::get() {
        cout << ": : get : :" << endl;
        return NULL;
    }

    int main()
    {
        A<int> a;
        a.get();
        a.sayHello(666);


        getchar();

        return 0;
    }

总结

1.template //泛型方法的声明
2.template //泛型类的声明
3.泛型参数,一般定义为T const&,但并不是必须的,这个在附录里有讲到。
4.不仅仅在声明的时候需要使用声明语句,在我们实现泛型方法的时候也需要用到泛型声明语句template 。

C++ 异常处理

try、catch、throw

  • throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
  • catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。
  • try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块

抛出异常

除0异常


    double division(int a, int b)
    {
       if( b == 0 )
       {
          throw "Division by zero condition!";
       }
       return (a/b);
    }

捕获异常

catch 块跟在 try 块后面,用于捕获异常。您可以指定想要捕捉的异常类型,这是由 catch 关键字后的括号内的异常声明决定的。


try
{
   // 保护代码
}catch( ExceptionName e )
{
  // 处理 ExceptionName 异常的代码
}

如果想让 catch 块能够处理 try 块抛出的任何类型的异常,则必须在异常声明的括号内使用省略号 …,如下所示:

    try
    {
       // 保护代码
    }catch(...)
    {
      // 能处理任何异常的代码
    }

Code

抛出一个除以零的异常,并在 catch 块中捕获该异常。


    #include <iostream>
    using namespace std;

    double division(int a, int b)
    {
        if (b == 0)
        {
            throw "Division by zero condition!";
        }
        return (a / b);
    }

    int main()
    {
        int x = 50;
        int y = 0;
        double z = 0;

        try {
            z = division(x, y);
            cout << z << endl;
        }
        catch (const char* msg) {//catch块跟抛出throw除的东西类型有对应,这里我们抛的一个字符串,它是const char*类型
            cerr << msg << endl;
        }

        getchar();
        return 0;
    }

C++有哪些种类的异常

参考:http://www.runoob.com/cplusplus/cpp-exceptions-handling.html

自定义异常


    #include <iostream>
    #include <exception>
    using namespace std;

    struct MyException : public exception
    {
      const char * what () const throw ()
      {
        return "C++ Exception";
      }
    };

    int main()
    {
      try
      {
        throw MyException();
      }
      catch(MyException& e)
      {
        std::cout << "MyException caught" << std::endl;
        std::cout << e.what() << std::endl;
      }
      catch(std::exception& e)
      {
        //其他的错误
      }
    }

附录

int const& 和 const int&有什么区别?
int const&表示此引用所代表的int类型变量无法使用此引用修改.
const int&表示此引用所代表的是const int类型变量,同样也无法用此引用修改.

两者的区别是:
int const&所代表的变量可以是int 和 const int .
const int&所代表的变量仅可以是 const int .

Thanks

http://www.runoob.com/cplusplus/cpp-exceptions-handling.html
本文Demo:https://github.com/zj614android/c-c-/tree/master/Lis8

猜你喜欢

转载自blog.csdn.net/user11223344abc/article/details/80581057