首页 > 编程语言 >C++基础

C++基础

时间:2024-01-18 17:58:04浏览次数:30  
标签:函数 派生类 基础 virtual C++ 基类 纯虚 name

一、理论

           1、虚函数

      1.1、定义:​       

          虚函数就是在类中被关键字virtual声明的函数,一般只在基类中声明虚函数。

          1.2、规则:

                                      1、虚函数必须是类的成员函数,不能是类的静态成员函数或友元函数,因为虚函数的调用要靠特定的对象来决定该激活哪个函数

                                      2、在派生类中需要定义与虚函数同名的函数(完全相同:函数类型、函数名、参数个数、参数类型顺序)

                                      3、类的构造函数不能是虚函数。因为虚函数是为了实现多态性,根据不同的对象在运行过程中才决定与哪个函数建立联系,而构造函数在对象创建时自动运行

                                     4、析构函数可以声明为虚函数,且通常都是被声明为虚函数

                                     5、基类的虚函数无论被公有继承多少次,在多级派生中仍然为虚函数(虽然派生类中可以省略virtual,但是为了能一眼辨认,建议不要省略)

                                     6、必须使用基类指针访问虚函数,才能获得运行的多态性。虽然可以使用对象名和点运算符(面向对象的方式)的方式来调用虚函数,但是这种调用是在编译时进行的,是静态联编,不能利用虚函数的好处

    1.3、作用:​

                                    允许通过基类类型的 指针或引用 来访问派生类中的同名函数。

                 

动态多态引出虚函数

例1

#include<iostream>
using namespace std;
class Animal
{
    public:
        //虚函数    父类的virtual必须写
        virtual void Speak()                //增加了个 virtual
        {
            cout<<"动物在说话"<<endl;
        }
}; 
class Cat : public Animal
{
    public:
            //重写   函数返回值类型  函数名 参数列表 完全相同
        (virtual) void Speak()        //对于子类 virtual可写可不写
        {
            cout<<"喵"<<endl;
        }
};
class Dog : public Animal
{
    public:
        void Speak()
        {
            cout<<"汪"<<endl;
        }
};
void doSpeak(Animal &animal)    //父类的引用指向子类对象
{
    animal.Speak();        //这个Speak拥有了多种形态,根据传入的对象不同,来表示调用函                        数的不同
}
void test()
{
    Cat cat;
    doSpeak(cat);
    
    Dog dog;
    doSpeak(dog);
}
int main()
{
    test();
    return 0;
} 

例二:

#include<iostream>
using namespace std;
class B1
{
    public:
        virtual void Display()
        {
            cout<<"基类B1"<<endl; 
        }
};
class B2
{
    public:
        virtual void Display()
        {
            cout<<"基类B2"<<endl;    
        }    
}; 
class B3 : public B1 ,public B2
{
    void Display()
    {
        cout<<"基类B3"<<endl;
    }
}; 
int main()
{
    B1 *b1,bb1;
    B2 *b2,bb2;
    B3 *b3,bb3;
    b1 = &bb1,b1 -> Display();
    
    b2 = &bb2,b2 -> Display();
    
    b1 = &bb3,b1 -> Display();
    
    b2 = &bb3,b2 -> Display();
    return 0;
} 

           2、纯虚函数

                          2.1、定义:

                              基类往往表示一种没有具体意义的抽象概念(或表示共性,但后代在共性的基础上又有差异性),即使虚函数在基类中不需要做任何工作,也要写出一个空的函数体。

                          2.2、语法

                             virtual 函数返回值类型 虚函数名(参数列表) = 0;

                          2.3、规则:

                                    1. 纯虚函数是一种没有函数体的特殊虚函数,声明时“= 0” 表示这是这是一个纯虚函数
                                    2. 纯虚函数不能被调用,只能在派生类中具体定义后才可调用
                                    3. 纯虚函数的作用在于基类给派生类提供一个标准的函数模型,统一的接口来实现动态多态,派生类根据需要写出纯虚函数的具体代码

                

#include<iostream>
using namespace std;
class Animal
{
    protected:
        string name;
        int age;
        
    public:
        Animal(string _name,int _age):name(_name),age(_age){}
        
        virtual void Behavior() = 0;
};
class Dog:public Animal
{
    public:
        Dog(string _name,int _age):Animal(_name,_age){}        //只能用列表法继承构造函数
        
        void Behavior()
        {
            cout<<"修勾名为:"<<name<<endl;
            cout<<"年龄为:"<<age<<endl;
        }
};
class Cat:public Animal
{
    public:
        Cat(string _name,int _age):Animal(_name,_age){}
        
        void Behavior()
        {
            cout<<"修猫名为:"<<name<<endl;
            cout<<"年龄为:"<<age<<endl;
        }
};
int main()
{
    Dog d1("大黄",3);
    Cat c1("憨憨",2);
    Animal *p;            //定义父类 对象指针
    p = &d1;            //指向子类对象
    p -> Behavior();    //父类对象指针调用子类函数
    p = &c1;
    p -> Behavior();    
    return 0;
}

 

二、基础类

1、map

       1.1,insert如键值以存在,不更新,返回失败。

                 更新代码如下:

map<string, int>    
    
auto it = m_map.find(name);

if(it != m_map.end())
       it->second = item;
else
       m_map.insert(make_pair(name, item));

 

2、vector 与 list区别

         vector 拥有一块连续的内存,因此支持随机访问,支持高效率的访问。

         list拥有一段不连续的内存空间,支持高效率的插入和删除,而不关心访问效率。

 

三、设计模式

标签:函数,派生类,基础,virtual,C++,基类,纯虚,name
From: https://www.cnblogs.com/wxzhrj/p/17973068

相关文章

  • RabbitMq基础版
    微服务一旦拆分,必然涉及到服务之间的相互调用,目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中,调用者发起请求后需要等待服务提供者执行业务返回结果后,才能继续执行后面的业务。也就是说调用者在调用过程中处于阻塞状态,因此我们成这种调用方式为同步调用,也可以叫同......
  • java 基础常见(上)
    titlecategorytagheadJava基础常见面试题总结(上)JavaJava基础metanamecontentkeywordsJVM,JDK,JRE,字节码详解,Java基本数据类型,装箱和拆箱metanamecontentdescription全网质量最高的Java基础常见知识点和面试题......
  • C++多线程
    C++多线程的语法以及使用1.线程的创建首先创建一个多线程入口函数threadmain,threadmain函数体中完成子线程所要做的事。接着在主函数中创建线程对象th,调用构造函数,并传递一个函数指针作为入口函数:threadth(treadmain);入口函数为thread构造函数的参数。之后在主线程中......
  • 20. 有效的括号C++
    括号匹配用栈是解决是最简单那的。遇到左括号就入栈。遇到右括号就出栈,然后看是否匹配。这里再用一个map把括号数字化会更简单。classSolution{public:boolisValid(strings){map<char,int>m={{'(',1},{')',-1},{'{',2},{'}',-......
  • 鸿蒙应用开发者基础认证考试(答案)
    高亮是易错题main_pages.json存放页面page路径配置信息。(正确)1.在stage模型中,下列配置文件属于AppScope文件夹的是?(C)A.main_pages.jsonB.module.json5C.app.json5(build-profile.json5)D.package.json2.module.json5配置文件中,包含了以下哪些信息?(ABD)A.ability的相......
  • KY109 Zero-complexity TranspositionC++
    h很简单的题目,不管是用数组还是用栈都非常简单。#include<iostream>#include<stack>usingnamespacestd;intmain(){intn;while(cin>>n){stack<long>s;while(n!=0){inttem;cin>>tem;......
  • ArkTS基础知识
    【习题】ArkTS基础知识 及格分85/ 满分100 判断题1. 循环渲染ForEach可以从数据源中迭代获取数据,并为每个数组项创建相应的组件。正确(True)错误(False)回答正确2. @Link变量不能在组件内部进行初始化。正确(True)错误(False)回答正确单......
  • 生成学习全景:从基础理论到GANs技术实战
    本文全面探讨了生成学习的理论与实践,包括对生成学习与判别学习的比较、详细解析GANs、VAEs及自回归模型的工作原理与结构,并通过实战案例展示了GAN模型在PyTorch中的实现。关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦......
  • 【scikit-learn基础】--『监督学习』之 谱聚类
    谱聚类算法基于图论,它的起源可以追溯到早期的图分割文献。不过,直至近年来,受益于计算机计算能力的提升,谱聚类算法才得到了广泛的研究和关注。谱聚类被广泛应用于图像分割、社交网络分析、推荐系统、文本聚类等领域。例如,在图像分割中,谱聚类可以有效地将图像划分为背景和前景;在社交......
  • C++内存分配揭秘:new操作符::operator new和Placement new的区别
     在C++中,new 操作符、::operatornew 和placementnew是用于动态内存分配的工具,但它们有不同的用法和行为。以下是它们的区别和用法的详细实例:1.new操作符new 操作符用于在堆上动态分配内存,并调用对象的构造函数初始化对象。#include<iostream>classMyClass{p......