您的位置:首页 > 编程语言 > C语言/C++

C++入门(14):动态内存管理

2016-01-11 17:45 465 查看

C++入门(14):动态内存管理

动态内存管理

动态内存只受限于计算机里的硬件内存总量。

从内存池申请一些内存使用 new 语句,new 语句返回新分配地址块的起始地址,如果没有足够的可用空间,new 语句将抛出
std::bad_alloc
异常;

使用完内存块之后,应该用 delete 语句把它还给内存池;

用 delete 语句把内存块“重置”为未分配状态,但那个指针占用的空间仍保留着,所以,在释放了内存块之后,还应该把与之关联的指针设置为 NULL(NULL定义在cstddef头文件中)。

把某个指针设置为NULL的目的是为了让程序明确地知道这个指针已不再指向一个内存块,从而确保此后对这个指针的任何引用(在把另一个值赋给它之前)都将失败。因为我们无法通过一个被设置为 NULL 的指针去访问数据,试图对一个NULL指针解引用将在运行时被检测到。

为对象分配内存

动态创建对象时,如果那个类的构造器有输入参数,则把它们放在类名后的括号里传递过去即可。

一般来说,如果想把一个某给定类型(比如int类型)的指针用作另一种类型(比如float类型)的指针,必须通过类型转换操作来转换那个指针;但是,当创建了一个指向某个类的指针时,我们可以把同一个指针直接用作该类的子类的指针而无需对它进行类型转换,比如:

[code]Pet *pet = new Pet("LittleSeven");     //Pet类为基类,创建一个基类指针
delete pet;
pet = NULL;
pet = new Dog("LittleSeven2") ;        //Dog类是Pet类的子类;此时不需要类型转换,可以直接使基类指针指向子类
delete pet;
pet = NULL;


注意:动态创建和使用对象时,一定要把方法声明为虚方法。

在需要传递一个指针作为输入参数的场合,如果要传入的是基类指针,则把其子类指针传过去也是安全的。

动态数组:为长度可变的数组分配内存。

分配时,比如
int *x = new int[count];
count 可以用户输入;删除时,比如
delete[] x;x = NULL;
即要在 delete 后加 [] ,来明确告诉编译器它应该删除一个数组。

下面通过代码具体了解一下C++动态分配内存的知识:

[code]#include <iostream>
#include <string>

class Pet{
    public:
        Pet(std::string name);
        virtual void play();
        virtual ~Pet();                        //把析构器定义为虚函数
    protected:
        std::string name;
};
class Dog : public Pet{
    public:
        Dog(std::string name, int cnt);
        ~Dog();
        void play();
        void bark();
    private:
        int cnt;
};
Pet::Pet(std::string name)
{
    this->name = name;
}
Pet::~Pet()
{
    std::cout << "It's Pet's destructor!\n";
}
void Pet::play()
{
    std::cout << name << " is playing..." << std::endl;
}

Dog::Dog(std::string name, int cnt):Pet(name)
{
    this->cnt = cnt;
}
Dog::~Dog()
{
    std::cout << "It's Dog's destructor!\n";
}
void Dog::play()
{
    std::cout << name << " plays " << cnt << " times a day..." << std::endl;
}
void Dog::bark()
{
    std::cout << name << " is barking...";
}

int main(int argc, char** argv) {

    std::cout << "Please enter a number to create an array...\n" ;
    int count;
    while(!(std::cin >> count))
    {
        std::cin.clear();
        std::cin.ignore(100,'\n');
        std::cout << "Please enter a number to create an array...\n" ;
    }
    std::cin.ignore(100,'\n');

    int *x = new int[count];                     //创建一个指向数组的指针
    for(int i = 0; i < count; i++)
    {
        x[i] = i;
    }
    for(int i = 0; i < count; i++)
    {
        std::cout << "The value of x[" << i << "] is " << x[i] << std::endl;
    }
    delete[] x;
    x = NULL;

    Pet *pet = new Pet("LS1");
    pet->play();
    delete pet;
    pet = NULL;
    pet = new Dog("LS2",3);                      //如果把临时分配的子类给一个基类指针,为了调用子类的析构器,必须把基类的析构器声明成虚析构器
    pet->play();
    delete pet;
    pet = NULL;

    return 0;
}


运行结果为:

[code]Please enter a number to create an array...
7
The value of x[0] is 0
The value of x[1] is 1
The value of x[2] is 2
The value of x[3] is 3
The value of x[4] is 4
The value of x[5] is 5
The value of x[6] is 6
LS1 is playing...
It's Pet's destructor!
LS2 plays 3 times a day...
It's Dog's destructor!
It's Pet's destructor!


C++入门(13):错误处理和调试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: