C++多态

多态:同一操作作用于不同对象时,产生不同的行为,分为编译时多态运行时多态

1.运行时多态(动态绑定)

1.虚函数
通过虚函数和基类指针/引用实现,具体调用那个函数在运行时决定。

class Shape {
public:
    Shape() {}
    virtual ~Shape() {}
    virtual void draw() {
        cout << "This is Shape::draw()" << endl;
    }
};
class Circle : public Shape {
public:
    Circle() {}
    virtual ~Circle() {}
    void draw() {
        cout << "This is Circle::draw()" << endl;
    }
};
Shape* shape = new Circle();
shape->draw();  //调用子类Circle的draw()函数
delete shape;

编译器为每个含虚函数的类生成一个虚函数表(vtable),存储函数指针,对象通过函数指针(vptr)访问。

2.纯虚函数与抽象类
纯虚函数(virtual void func() = 0;)强制基类必须实现同名的函数,此时基类变为抽象类,不能实例化。

class Shape {
public:
    Shape() {}
    virtual ~Shape() {}
    virtual void draw() = 0;//纯虚函数
};

class Circle : public Shape {
public:
    Circle() {}
    virtual ~Circle() {}
    void draw() {
        cout << "This is Circle::draw()" << endl;
    }
};

int main() {
    //Shape* shape = new Shape();//编译不通过,报错invalid new-expression of abstract class type ‘Shape’
    Shape* shape = new Circle();
    shape->draw();  //调用子类Circle的draw()函数
    delete shape;
    return 0;
}

3.典型考题

  • 求类大小
class Shape1 {
public:
    Shape1() {}
    ~Shape1() {}
};
class Shape2 {
public:
    Shape2() {}
    virtual ~Shape2() {}
    virtual void draw() = 0; 
};
cout << sizeof(Shape1) << endl; //输出1
cout << sizeof(Shape2) << endl; //输出8,因为需要存虚函数表指针,所以大小为8(在32位机结果为4)
  • 析构函数必须为虚函数
class Base {
public:
    Base() {}
    ~Base() {}
    virtual void PrintData() = 0;
};

class Derive : public Base {
public:
    Derive(int data) : data(new int(data)) {}
    ~Derive()
    {
        cout << "Delete data." << endl;
        delete data;
    }
    void PrintData() override
    {
        cout << "Data: " << *data << endl;
    }
private:
    int *data;
};

int main() {
    Base* base = new Derive(2);
    delete base;
    return 0;
}

上述代码有什么错误?

  • 当通过基类指针删除派生类对象时,若基类析构函数非虚函数,则派生类的析构函数不会被调用,导致内存泄漏。

2.编译多态

  • 函数重载(Overload): 统一作用域内同名函数参数不同。
  • 模板(Templaye):泛型编程,根据类型生成不同代码。
posted @ 2025-03-31 11:31  ydqun  阅读(13)  评论(0)    收藏  举报