C++继承和动态内存分配

目录
  • 1.简介
  • 2.派生类不用new
  • 3.派生类使用new

文章转自微信 公众号:Coder梁(ID:Coder_LT)

1.简介

这里面有一个问题,当我们的基类使用动态内存分配,并且重新定义赋值和复制构造函数,这会对派生类的实现有什么影响呢?

我们来看两种情况:

2.派生类不用new

假设基类中使用了动态内存分配:

class baseDMA {
 private:
     char *label;
     int rating;
    public:
     baseDMA(const char* l="null", int r=0);
     baseDMA(const baseDMA& rs);
     virtual ~baseDMA();
     baseDMA &operator=(const baseDMA& rs);
};

在这个声明里包含了构造函数、析构函数、复制构造函数和重载赋值运算符。

现在假设我们从baseDMA派生出了类lackDMA,但是后者不使用new

class lackDMA: public baseMDA {
   private:
     char color[40];
    public:
     ...
};

问题来了,我们要不要给lackDMA这个类定义析构函数、复制构造函数和赋值运算符呢?

答案是不需要。

首先是析构函数,这个很好想明白,如果我们没有定义析构函数,那么编译器会自动定义一个不执行任何操作的默认析构函数。实际上派生类的析构函数往往会在执行一些逻辑之后调用基类的构造函数,因为lackDMA类中的成员不是通过new创建的,因此不需要额外的操作,所以默认析构函数是合适的。

同样的默认复制构造函数也会执行非new创建成员的复制,所以对于color变量来说是没问题的。并且在派生类当中,默认复制构造函数除了会复制非new创建的成员之外,还会调用基类的复制构造函数来复制父类成员的部分。所以,对于派生类lackDMA来说,我们使用默认的复制构造函数一样没有问题。

赋值也是一样的,默认的赋值运算符也会自动使用基类的赋值运算符来对基类的成员进行赋值。

3.派生类使用new

我们再来看看派生类当中使用了new的情况。

class hasDMA: public baseMDA {
   private:
     char *style;
    public:
     ...
};

hasDMA这个类当中,我们添加了一个需要使用new创建的char*成员。在这种情况下,我们就没办法使用默认的函数了,就必须定义显式析构函数、复制构造函数和赋值运算符了,我们一个一个来看。

首先是析构函数,派生类的析构函数会自动调用基类的析构函数,所以我们只需要在析构函数当中释放派生类中独有的成员变量即可。

hasDMA::~hasDMA() {
    delete []style;
}

然后我们再来看看拷贝构造函数,由于派生类不能访问基类private成员,所以我们需要调用基类的拷贝构造函数。

hasDMA::hasDMA(const hasDMA& hs): baseDMA(hs) {
    style = new char[std::strlen(hs.style) + 1];
    std::strcpy(style, hs.style);
}

最后是赋值运算符,同样,由于派生类不能访问基类中私有成员,我们也需要借助基类的赋值运算符:

hasDMA &hasDMA::operator(const hasDMA& hs) {
    if (this == &hs) return *this;
    baseDMA::operator=(hs);
    delete []style;
    style = new char[std::strlen(hs.style) + 1];
    std::strcpy(style, hs.style);
    return *this;
}

这当中有一个语句看起来有些奇怪:

baseDMA::operator=(hs);

这是我们手动显式调用了基类的赋值运算符,我们直接用等于号赋值也有同样的效果:

*this = hs;

为什么不这么干呢?这是因为编译器在执行的时候会默认调用子类的赋值运算符hasDMA::operator=,从而导致一直递归导致死循环。

所以我们需要手动写明作用域解析符,表明这是调用的父类赋值运算符,而非派生类的运算符,这一点比较隐晦,要千万注意。

到此这篇关于C++继承和动态内存分配的文章就介绍到这了,更多相关C++继承和动态内存分配内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++ 中继承与动态内存分配的详解

    C++ 中继承与动态内存分配的详解 继承是怎样与动态内存分配进行互动的呢?例如,如果基类使用动态内存分配,并重新定义赋值和复制构造函数,这将怎样影响派生类的实现呢?这个问题的答案取决于派生类的属性.如果派生类也使用动态内存分配,那么就需要学习几个新的小技巧.下面来看看这两种情况: 一.派生类不使用new 派生类是否需要为显示定义析构函数,复制构造函数和赋值操作符呢? 不需要! 首先,来看是否需要析构函数,如果没有定义析构函数,编译器将定义一个不执行任何操作的默认构造函数.实际上,派生类的默认构造

  • C++继承和动态内存分配

    目录 1.简介 2.派生类不用new 3.派生类使用new 文章转自微信 公众号:Coder梁(ID:Coder_LT) 1.简介 这里面有一个问题,当我们的基类使用动态内存分配,并且重新定义赋值和复制构造函数,这会对派生类的实现有什么影响呢? 我们来看两种情况: 2.派生类不用new 假设基类中使用了动态内存分配: class baseDMA {  private:      char *label;      int rating;     public:      baseDMA(cons

  • C语言动态内存分配的详解

    C语言动态内存分配的详解 1.为什么使用动态内存分配 数组在使用的时候可能造成内存浪费,使用动态内存分配可以解决这个问题. 2. malloc和free C函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和释放. (1)void *malloc(size_t size); malloc的参数就是需要分配的内存字节数.malloc分配一块连续的内存.如果操作系统无法向malloc提供更多的内存,malloc就返回一个NULL指针. (2)void free(void *poi

  • C++动态内存分配(new/new[]和delete/delete[])详解

    C++动态内存分配(new/new[]和delete/delete[])详解 为了解决这个普通的编程问题,在运行时能创建和销毁对象是基本的要求.当然,C已提供了动态内存分配函数malloc( )和free( ),以及malloc( )的变种(realloc:改变分配内存的大小,calloc:指针指向内存前初始化),这些函数在运行时从堆中(也称自由内存)分配存储单元,但是运用这些库函数需要计算需要开辟内存的大小,容易出现错误. 那么通常我们在C语言中我们开辟内存的方式如下: (void*)mall

  • C语言 动态内存分配的详解及实例

    1. 动态内存分配的意义 (1)C 语言中的一切操作都是基于内存的. (2)变量和数组都是内存的别名. ①内存分配由编译器在编译期间决定 ②定义数组的时候必须指定数组长度 ③数组长度是在编译期就必须确定的 (3)但是程序运行的过程中,可能需要使用一些额外的内存空间 2. malloc 和 free 函数 (1)malloc 和 free 用于执行动态内存分配的释放 (2)malloc 所分配的是一块连续的内存 (3)malloc 以字节为单位,并且返回值不带任何的类型信息:void* mallo

  • C语言 动态内存分配详解

    C语言 动态内存分配详解 动态内存分配涉及到堆栈的概念:堆栈是两种数据结构.堆栈都是数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除. 栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表. \在C语言中,全局变量分配在内存中的静态存储区,非静态的局部变量(包括形参)是分配在内存的动态存储区,该存储区被

  • 详解C++ 动态内存分配与命名空间

    1.C++中的动态内存分配 通过new关键字进行动态内存申请 C++中的动态内存申请时基于类型进行的 delete关键用于内存释放 C语言其实是不支持动态内存分配的,是通过malloc库函数来实现的,可能有一些硬件根本不支持malloc:而C++ new是一个关键字,不管在任意编译器上,任意硬件平台上都是能够进行动态内存分配的,这是本质区别. malloc是基于字节来进行动态内存分配的,new则是基于类型来进行动态内存分配 // 变量申请: Type * pointer = new Type;

  • 动态内存分配导致影响Javascript性能的问题

    内存分配对性能的影响是很大的,分配内存本身需要时间,垃圾回收器回收内存也需要时间,所以应该尽量避免在堆里分配内存.不过直到最近优化HoLa cantk时,我才深刻的体会到内存分配对性能的影响,其中有一个关于arguments的问题挺有意思,写在这里和大家分享一下. 我要做的事情是用webgl实现canvas的2d API(这个话题本身也是挺有意思的,有空我们再讨论),drawImage是一个重要的函数,游戏会频繁的调用它,所以它的性能至关重要.drawImage的参数个数是可变的,它有三种形式:

  • c语言动态内存分配知识点及实例

    c语言怎么实现动态内存分配 我们经常会预先给程序开辟好内存空间,然后进行操作. int arr[5] ; 对这个数组我们在定义的时候必须给提前开辟好空间,并且在程序执行的过程中,这个开辟的内存空间是一直存在的,除非等到这个函数执行完毕,才会将空间释放.有个问题就是这个数组在程序中无法被修改. 这些问题给我们造成了一些使用上的不方便,所以,C中提供了malloc()函数. 关于malloc()函数,这个函数它接受一个参数:就是所需的内存的字节数.然后malloc()找到可用内存中那一个大小适合的块

  • c++ 动态内存分配相关总结

    下面随笔是关于c++动态内存分配. 动态申请内存操作符 new new 类型名T(初始化参数列表) 功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值. 结果值:成功:T类型的指针,指向新分配的内存:失败:抛出异常. 释放内存操作符delete delete 指针p 功能:释放指针p所指向的内存.p必须是new操作的返回值. //例1 动态创建对象举例 #include <iostream> using namespace std; class Point { pub

随机推荐