B是A的子类,子类会继承父类的public方法,子类对象可以调用父类的public接口,但是子类和父类函数重名时,父类的方法会被子类覆盖(隐藏),子类调用和父类同名同参函数或者重载父类的函数后不可以直接调用父类函数,需要加A::fun()调用,父类的protect方法只在继承中有效,子类可以调用父类的protect方法,但是外部无法访问,所以在非继承关系中protect与private等同,private方法只能由类内部的方法调用,也可以由友元函数和类调用,其他对象都不可以访问类的private数据。
父类对象指向子类时只能调用子类从父类继承到的一部分函数,不可以调用子类新增的函数,所以指针向上转化是安全的,向下转化有问题,dynamic_cast会返回一个空指针。多态是指父类对象可以指向并调用子类中和父类同名同参函数,通过虚函数来实现,父类中定义的虚函数在子类不定义也是虚函数。虚函数通过虚函数表实现,32位机器的编译器有虚函数的类会多出4个字节的虚函数指针,指向虚函数表中的第一个虚函数,当父类对象指向子类并调用虚函数的时候,便从子类的虚函数表中找出对应的同名同参函数。纯虚函数是如同virtual fun(){}=0的函数,存在纯虚函数的类称为抽象类(纯虚类),抽象类不可以建立实例对象,只能由子类重写其纯虚函数。举个例子就如动物类virtual eat(){}=0而狗类virtual eat(){cout<<"bone"<<endl;}一个抽象类可以定义多个虚函数,均通过指向不同的子类对象由子类对象实例化,若子类未实例化纯虚函数,则子类也为抽象类,等待孙子类来实例化纯虚函数,才可以建立对象。纯虚类和虚基类不同,虚基类仅仅出现在多重继承关系中,虚继承使多个派生类共用一份基类的成员(基类必须使用默认构造函数才可以虚继承),并消除菱形继承中的孙子类歧义,应尽量避免多重继承的使用。
类是对象的抽象,对象是类的实例。一个空类中存在默认构造函数,默认析构函数,默认拷贝构造函数(浅拷贝),默认运算符重载“=”,默认取地址符&和const取地址符&,当使用const取址的时候,需要注意const在*之后是说指针不允许指向其他的对象,而const在*之前才是说不允许使用指向该类的指针改变该类的任何成员,而且只能调用类的const方法。还有一个需要注意的是new和malloc可以在堆中创建对象,但malloc只是库函数,而new是运算符,只有new可以创建类对象,因为new可以自动调用类的默认构造函数并创建类的实例而malloc不可以。在类的内部一旦发生在堆上使用malloc或者new申请空间的事件的时候,需要注意默认拷贝构造函数和默认重载运算符“=”可能导致指针悬空问题,可能导致两个对象同时指向堆中的一块空间,在析构的时候会导致重复析构。如果需要用,需要重写默认拷贝构造函数和“=”重载,为新对象在堆中申请相应的空间。深拷贝:
- Person(const Person &p)
- {
- m_name = new char[strlen(p.m_name)+1];
- if (m_name != 0)
- {
- strcpy(m_name,p.m_name);
- m_age = p.m_age;
- }
- }
- class STU
- {
- public:
- STU(string _name,string _sex,int _age):name(_name)
- {
- sex=_sex;
- age=_age;
- }
- void printStu()
- {
- cout<<"姓名:"<<name<<endl<<"性别:"<<sex<<endl<<"年龄:"<<age<<endl;
- }
- private:
- string name;
- string sex;
- int age;
- };
#include
<iostream> using namespace std; class Person{ public : ~Person(){ //declare
destructor as a virtual function cout
<< "Person::~Person()" <<
endl; } }; class Student
: public Person{ public : ~Student(){ //
virtual or not is OK cout
<< "Student::~Student()" <<
endl; } }; int main(){ Person
*pt1 = new Person; Person
*pt2 = new Student; //
base class pointer point to derived class //
Student *pt3 = new Person; // derived class pointer can not point to base class Student
*pt4 = new Student; delete pt1; cout
<< "*********" <<
endl; delete pt2; cout
<< "*********" <<
endl; //delete
pt3; //cout
<< "*********" << endl; delete pt4; cout
<< "*********" <<
endl; return 0; } |
运行结果:
-
#include<iostream>
-
using namespace std;
-
template <typename T>
-
class Base
-
{
-
friend T;
-
private:
-
Base() {}
-
~Base() {}
-
};
-
-
class Finalclass : virtual public Base<Finalclass>
-
{
-
public:
-
Finalclass() {}
-
~Finalclass() {}
-
};
-
void main()
-
{
-
Finalclass *p = new Finalclass; //堆上对象
-
Finalclass fs; //栈上对象
- }