首页 > 编程语言 >C++精品小案例:C++中的多态性及其实现、模板元编程及其在C++中的应用

C++精品小案例:C++中的多态性及其实现、模板元编程及其在C++中的应用

时间:2024-03-29 19:02:07浏览次数:28  
标签:std 函数 多态性 C++ MyClass shared ptr 模板 指针

1. C++中的多态性及其实现

多态性是面向对象编程的三大特性之一,它允许使用父类类型的指针或引用来指向子类对象,并通过这个父类类型的指针或引用来调用实际子类的成员函数。这样,就可以在运行时确定应该调用哪个具体的函数实现,从而实现一个接口多种形态。

多态性主要通过虚函数来实现。在基类中声明一个虚函数,然后在派生类中重写这个函数。当使用基类指针或引用来调用这个函数时,会根据实际指向的对象类型来调用相应的函数实现。

例如:


cpp复制代码

class Animal {
public:
virtual void speak() { // 虚函数
std::cout << "The animal speaks" << std::endl;
}
};
class Dog : public Animal {
public:
void speak() override { // 重写虚函数
std::cout << "The dog barks" << std::endl;
}
};
class Cat : public Animal {
public:
void speak() override { // 重写虚函数
std::cout << "The cat meows" << std::endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->speak(); // 输出 "The dog barks"
animal2->speak(); // 输出 "The cat meows"
delete animal1;
delete animal2;
return 0;
}

在这个例子中,Animal 类有一个虚函数 speak()Dog 和 Cat 类都重写了这个函数。当通过 Animal 类型的指针调用 speak() 函数时,实际调用的是 Dog 或 Cat 类的 speak() 函数,这就是多态性的体现。

2. 智能指针及其类型

智能指针是C++11引入的一种特性,用于自动管理动态分配的内存,以避免内存泄漏。智能指针在对象离开作用域时会自动删除它所指向的对象,因此不需要显式调用 delete

C++中主要有以下几种智能指针:

  • std::unique_ptr:独占所有权的智能指针,同一时间只能有一个 unique_ptr 指向某个对象。当 unique_ptr 被销毁(例如离开作用域)时,它所指向的对象也会被自动删除。
  • std::shared_ptr:共享所有权的智能指针,可以有多个 shared_ptr 指向同一个对象。当最后一个指向某个对象的 shared_ptr 被销毁时,该对象才会被删除。
  • std::weak_ptr:一种不控制所指向对象生存期的智能指针,它指向一个由 shared_ptr 管理的对象。其目的是解决 shared_ptr 相互引用导致的循环引用问题。

例如:


cpp复制代码

#include <memory>
#include <iostream>
class MyClass {
public:
~MyClass() {
std::cout << "Deleting MyClass" << std::endl;
}
};
int main() {
// 使用 unique_ptr
std::unique_ptr<MyClass> ptr1(new MyClass());
// 当 ptr1 离开作用域时,MyClass 对象将被自动删除
// 使用 shared_ptr
std::shared_ptr<MyClass> ptr2(new MyClass());
std::shared_ptr<MyClass> ptr3 = ptr2; // ptr2 和 ptr3 共享所有权
// 当 ptr2 和 ptr3 都离开作用域时,MyClass 对象才会被删除
// 使用 weak_ptr 解决循环引用问题(这里仅展示 weak_ptr 的基本用法)
std::shared_ptr<MyClass> ptr4(new MyClass());
std::weak_ptr<MyClass> wptr = ptr4;
// wptr 不控制 MyClass 对象的生命周期,但它可以用来观察对象是否还存在
return 0;
}

3. 模板元编程及其在C++中的应用

模板元编程是C++的一种编程技术,利用模板在编译期进行计算和操作类型。它允许程序员在编译时创建和操作类型,从而实现一些高级功能,如类型特性检测、类型转换、生成代码等。模板元编程主要基于模板特化和递归模板展开。

模板元编程的一个典型应用是编写类型安全的容器或算法,它可以在不增加运行时开销的情况下提高代码的安全性和灵活性。

例如,我们可以使用模板元编程来实现一个简单的编译期阶乘函数:


cpp复制代码

template<int N>
struct Factorial {
enum { value = N * Factorial<N - 1>::value

标签:std,函数,多态性,C++,MyClass,shared,ptr,模板,指针
From: https://blog.csdn.net/guoche7/article/details/137153911

相关文章

  • C++继承详解
    文章目录前言一、继承的概念二、基类和派生类对象赋值转换三、继承中的作用域,隐藏四、菱形继承,菱形虚拟继承五、子类的默认成员函数六.继承和组合总结前言在本篇文章中我们将会学到有关继承方面的知识,其中C++中三大特性分别为:封装,继承多态。由此可见继承在学习中的......
  • WPF中使用PDF模板实现PDF导出和预览-来自GPT4
    在C#和WPF项目中实现加载不同的PDF模板、查看报告和导出PDF文件的功能,可以通过以下步骤完成:1.选择PDF库首先,选择一个合适的.NETPDF库。有许多库可以帮助你处理PDF文件,包括但不限于:iTextSharp:一个功能强大的和灵活的库,适用于创建和修改PDF文件。它是iText的一个.NET端口。......
  • 【C++杂货铺】内管管理
    目录......
  • 【Vue】模板语法
    用js完成输出输入框中的值到列表中constbuttonEl=document.querySelector('button');constinputEl=document.querySelector('input');constlistEl=document.querySelector('ul')0;functionaddGoal(){ constenteredValue=inputEl.value; c......
  • 阶乘(C++实现)
    阶乘是基斯顿·卡曼(ChristianKramp,1760~1826)于1808年发明的运算符号,是数学术语。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。1808年,基斯顿·卡曼引进这个表示法。公式表示为:0!=1n!= ()阶乘运算在C++语言中的实现,代......
  • 【模板】快速读入
    1inlineintread()2{3intw=0,s=1;4charch=getchar();5while(ch<'0'||ch>'9')6{7if(ch=='-')s=-1;8ch=getchar();9}10while(ch>='0'&&ch<='9')11{12w=w*10+ch......
  • 以下是一个简单的C++程序,用于生成斐波那契数列的前n项
    斐波那契数列是一个在自然界中广泛出现的数列,其定义是:第一个和第二个数都是1,从第三个数开始,每一个数都是前两个数之和。斐波那契数列的前几项是:1,1,2,3,5,8,13,21,34,55,…以下是一个简单的C++程序,用于生成斐波那契数列的前n项:#include<iostream>#include<ve......
  • C++从入门到精通——函数重载
    函数重载前言一、函数重载概念二、函数重载的分类参数类型不同的函数重载参数个数不同的函数重载参数类型顺序不同的函数重载三、函数重载的具体代码展示main.cpp四、为什么为什么C++支持函数重载,而C语言不支持函数重载呢前言函数重载是指在同一个作用域内,可以定......
  • C++从入门到精通——缺省参数
    缺省参数前言一、缺省参数概念二、缺省参数分类位置参数的缺省参数全缺省参数半缺省参数关键字参数的缺省参数函数指针的缺省参数`lambda`表达式三、缺省参数的具体代码展示main.cpp前言缺省参数是在函数定义时指定的默认值,当调用函数时未提供该参数的值时,将使......
  • c++基础知识
    deque的用法#include<deque>deque<type>d;//定义一个dequepush_back()//在队列的尾部插入元素。push_front()//在队列的头部插入元素。pop_back()//删除队列尾部的元素。pop_front()//删除队列头部的元素。back()//返回队列尾部元素的引用。front()//返回队列头部元素......