文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++支持几种不同形式的多态?深度解析与实践

2024-11-29 17:57

关注

一、编译时多态(静态多态)

1. 函数重载(Function Overloading)

函数重载是指在同一个作用域内,可以有多个同名函数,但它们的参数列表(参数的类型、个数或顺序)不同。编译器在编译时根据调用时提供的参数决定使用哪个函数。

示例代码:

#include 

void print(int i) {
    std::cout << "整数: " << i << std::endl;
}

void print(double d) {
    std::cout << "浮点数: " << d << std::endl;
}

void print(const std::string& s) {
    std::cout << "字符串: " << s << std::endl;
}

int main() {
    print(10);        // 调用print(int)
    print(3.14);      // 调用print(double)
    print("Hello");   // 调用print(const std::string&)
    return 0;
}

2. 模板(Templates)

模板允许我们编写泛型代码,支持在编译时根据具体类型实例化相应的函数或类。模板极大地提高了代码的复用性和灵活性。

示例代码:

#include 

template 
void swap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    swap(x, y);       // 实例化swap(int&, int&)
    std::cout << "x: " << x << ", y: " << y << std::endl;

    double m = 1.1, n = 2.2;
    swap(m, n);       // 实例化swap(double&, double&)
    std::cout << "m: " << m << ", n: " << n << std::endl;

    return 0;
}

二、运行时多态(动态多态)

1. 基于继承的多态(虚函数)

运行时多态通常通过继承和虚函数来实现。基类定义虚函数,而派生类重写这些虚函数。在运行时,根据实际对象的类型调用相应的重写函数。

示例代码:

#include 

class Animal {
public:
    virtual ~Animal() {}       // 虚析构函数,确保派生类对象正确析构
    virtual void makeSound() const = 0; // 纯虚函数,让Animal成为抽象类
};

class Dog : public Animal {
public:
    void makeSound() const override {
        std::cout << "汪汪汪" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() const override {
        std::cout << "喵喵喵" << std::endl;
    }
};

int main() {
    Animal* animals[] = { new Dog(), new Cat() };
    
    for (Animal* animal : animals) {
        animal->makeSound(); // 根据实际对象类型调用Dog::makeSound或Cat::makeSound
    }

    // 释放内存
    for (Animal* animal : animals) {
        delete animal;
    }

    return 0;
}

2. 基于函数指针的多态

在某些情况下,我们可能不希望使用继承和虚函数来实现多态,而是希望通过函数指针来实现。这种方式在某些性能敏感的场景下可能更高效,因为它避免了虚函数表的开销。

示例代码:

#include 
#include 
#include 

// 定义一个函数类型
using MakeSoundFunc = std::function;

class Animal {
public:
    Animal(MakeSoundFunc makeSound) : makeSound_(makeSound) {}
    void makeSound() const {
        makeSound_();
    }
private:
    MakeSoundFunc makeSound_;
};

int main() {
    auto dogSound = []() { std::cout << "汪汪汪" << std::endl; };
    auto catSound = []() { std::cout << "喵喵喵" << std::endl; };

    Animal dog(dogSound);
    Animal cat(catSound);

    std::vector animals = { dog, cat };

    for (const auto& animal : animals) {
        animal.makeSound(); // 通过函数指针调用相应的声音
    }

    return 0;
}

3. 基于CRTP(Curiously Recurring Template Pattern)的多态

CRTP是一种模板设计模式,它通过静态多态实现类似动态多态的行为,同时避免了虚函数表的开销。CRTP利用模板和继承,使基类能够调用派生类的实现。

示例代码:

#include 

// 基类模板
template 
class Animal {
public:
    void makeSound() const {
        // 强制转换为派生类,调用派生类的实现
        static_cast(this)->makeSoundImpl();
    }
};

// 派生类
class Dog : public Animal {
public:
    void makeSoundImpl() const {
        std::cout << "汪汪汪" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSoundImpl() const {
        std::cout << "喵喵喵" << std::endl;
    }
};

int main() {
    Dog dog;
    Cat cat;

    Animal& animalDog = dog;
    Animal& animalCat = cat;

    animalDog.makeSound(); // 调用Dog::makeSoundImpl
    animalCat.makeSound(); // 调用Cat::makeSoundImpl

    return 0;
}

三、总结

在C++中,多态性可以通过多种不同的形式实现,每种形式都有其独特的适用场景和优势:

来源:鲨鱼编程内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯