-
<table><tbody><tr class="firstRow"><td>123</td><td><code>Person *p=</code><code>new</code> <code>Soldier;</code><code>//用父类Person的指针指向堆中分配的子类Soldier的对象</code><code>delete</code> <code>p;</code><code>p=NULL;</code><code>//只执行父类的析构函数,而不执行子类的析构函数,可能导致内存泄露</code></td></tr></tbody></table><p>【如何在这种情况下防止内存泄露?】</p><p>虚析构函数:当存在继承关系,且要用一个父类的指针指向堆中子类的对象,并希望用父类的指针释放这块内存时,可以使用。</p><table ><tbody><tr class="firstRow"><td>12345</td><td><code>class</code> <code>Person{</code><code> </code><code>Person();</code><code> </code><code>virtual</code><code>~Person(); </code><code>//前面加关键字virtual即可,这个关键字可以被继承下去</code><code>}</code><code>//在Soldier.h中,即使在~Soldier前面不写virtual,也相当于有了这个关键字(被继承下来了)</code></td></tr></tbody></table><p>!</p><p><br/></p>查看全部
-
派生类的对象可以赋值的基类,而基类的对象不能赋值给派生类
123456 Soldier s1;
Person p1=s1;
Person *p2=&s1;
//这三行是正确的
s1=p1;
Soldier *s2=&p1;
//这两行是错误的
对于作为函数参数时:
1234567 void
fun(Person *p){...}
int
main(){
Person p1;
Soldier s1;
fun(&p1);
fun(&s1);
//这两种都是正确的
}
用子类对象初始化父类对象时,从父类中继承下来的属性会被初始化,而子类中特有的属性则会被截断(不会赋值给父类)。
查看全部 -
子类和父类中的同名函数不能进行重载,只能进行隐藏。
查看全部 -
私有继承中,在子类中可以访问父类的保护成员。B类由A类私有派生,那么在B类中可以访问A类的public、protected,但是不能访问A类的private。在B类外,B类对象不能访问A类的成员,只能访问B类的public。C类由B类私有派生,那么C类中不能访问B类的private(其中包含了A类的public、protected),但是可以访问B类的public、protected。在C类外,C类对象只能访问C类的public。
查看全部 -
private继承方式 基类成员访问属性 派生类成员访问属性
private成员 无法访问
protected成员 private
public成员 private
查看全部 -
protected 继承方式: 基类成员访问属性 派生类成员访问属性
private成员 无法访问
protected成员 protected
public成员 protected
查看全部 -
public继承方式:基类成员访问属性 派生类成员访问属性
private成员 无法访问
protected成员 protected
public成员 public
查看全部 -
公有继承:class A : public B
保护继承: class A : protected B
私有继承; class A : private B
查看全部 -
//声明2个类 class Person { public: Person(); ~Person(); void eat(); string m_strName; int m_iAge; }; class Worker: public Person { public: Worker(); ~Worker(); void work(); int m_iSalary; }; //定义2个类 Person::Person() { cout<<"Person()"<<endl; } Person::~Person() { cout<<"~Person()"<<endl; } void eat() { cout<<"eat()"<<endl; } //定义worker类的函数 Worker::Worker() { cout<<"Worker()"<<endl; } Worker::~Worker() { cout<<"~Worker()"<<endl; } void work() { cout<<"work()"<<endl; } //应用 Worker *p = new Worker(); p->m_strName = "jim"; p->m_iAge = 10; p->eat(); p->m_iSalary =100; p->work(); delete p; p = NULL; //先调用Person,再Worker,析构相反
查看全部 -
什么是继承,为什么要继承?
基类----派生类
父类 ----子类
class worker : public person
{
public:
void work();
int m_iSalary;
}
//工人类继承了人类,就不需要重新写人类的属性,只写自己的属性;工人类是人类的派生类,人类是工人类的基类;人类是父类,工人是子类。
所以派生类和基类是一起组合,父类和子类是一起组合
查看全部 -
没有虚析构函数的话,继承后申请的堆内存在释放时只释放一次,内存泄漏,虚析构函数,可以完整释放堆空间
查看全部 -
子类和父类的重名函数无法形成重载,只能进行隐藏
查看全部 -
父类子类变量同名,调用的是子类变量,若调父类变量加作用域
查看全部 -
公有继承
保护继承
私有继承
查看全部 -
公有继承总结
查看全部
举报