首页 > 其他分享 >27.final和override关键字

27.final和override关键字

时间:2023-07-03 21:35:34浏览次数:32  
标签:27 name Dog Animal override final 类中 构造函数

在C++中,final是一个关键字,用于修饰类的成员变量和成员函数。

1.final修饰成员变量:当一个类中的成员变量被声明为final时,它就变成了常量,即它的值不能再被修改。final修饰的成员变量必须在类定义中进行初始化,且只能初始化一次。

假设我们有一个名为Person的类,其中包含一个成员变量name,我们想将其声明为final:

class Person
{
public:
    final string name; // 将name声明为final 
    Person(string n) : name(n) {} // 初始化name
};

现在,我们可以创建一个Person对象并初始化其name属性:

int main()
{
    Person p("Alice"); // 正确使用final修饰的成员变量
    p.name = "Bob"; // 错误:无法修改final修饰的成员变量
    return 0;
}

在这个例子中,我们将name变量声明为final,这意味着它不能被修改。当我们尝试将其值更改为"Bob"时,编译器会报错,因为这是不允许的。只有在类定义中进行初始化后,我们才能访问和修改name变量的值。

2.final修饰成员函数:当一个类中的成员函数被声明为final时,它就变成了不可调用的虚函数,即它的指针不能被指向派生类的函数重载覆盖。final修饰的成员函数必须在类定义中进行声明,且只能声明一次。

class MyClass 
{
public:
    void foo() const final; // foo是final修饰的成员函数
};

class MyDerivedClass : public MyClass 
{
public:
    void foo() const override final; //error: cannot override 'const' final function 'MyClass::foo() const'
};

3.final修饰构造函数:当一个类中的构造函数被声明为final时,它就变成了不可调用的构造函数,即它的指针不能被指向派生类的构造函数重载覆盖。final修饰的构造函数必须在类定义中进行声明,且只能声明一次。

当一个类中的构造函数被声明为final时,它就不能被派生类的构造函数重载覆盖,也就是说,派生类不能再定义与该构造函数相同的构造函数。这样可以保证该类的对象在创建时一定会调用该构造函数,从而保证了该类的一些重要属性或状态的初始化。

举个例子,假设有一个基类Animal,其中有一个构造函数Animal(string name),用于初始化动物的名字。现在我们希望这个构造函数不能被派生类重载覆盖,可以将其声明为final:

class Animal 
{
public:
    final Animal(string name) : m_name(name) {}
    // ...
private:
    string m_name;
};

class Dog : public Animal 
{
public:
    // 这里无法定义与Animal(string name)相同的构造函数
    // ...
};

这样,无论是Dog还是其他派生类,都不能再定义与Animal(string name)相同的构造函数,从而保证了Animal类的对象在创建时一定会调用该构造函数。

如果将Animal类中的构造函数声明从final改为不final,那么在Dog类中就可以定义与Animal(string name)相同的构造函数了。这将导致一个问题:当创建一个Dog对象时,会调用哪个构造函数?

在这种情况下,编译器将选择调用Dog类中的构造函数,而不是Animal类中的构造函数。这意味着,Dog类的构造函数将覆盖Animal类的构造函数,并且Dog对象的属性将被初始化为默认值。

因此,如果您希望确保在创建Animal对象时始终调用其构造函数,则应将其构造函数声明为final。如果您希望允许派生类定义与其基类构造函数相同的构造函数,则应将其构造函数声明为非final。

下面是一个例子,展示了将Animal类中的构造函数声明从final改为非final后,Dog类可以定义与Animal(string name)相同的构造函数的情况:

#include <iostream>
#include <string>
using namespace std;

class Animal
{
public:
    Animal(string name) : m_name(name) {}
    void setName(string name) { m_name = name; }
private:
    string m_name;
};

class Dog : public Animal 
{
public:
    Dog(string name) : Animal(name) {} // 这里可以定义与Animal(string name)相同的构造函数了
    void bark() { cout << "Woof!" << endl; }
};

int main()
{
    Dog dog("Buddy");
    dog.setName("Rover");
    dog.bark();
    return 0;
}

在上面的例子中,我们创建了一个名为Dog的派生类,它继承自Animal类。在Dog类中,我们定义了一个与Animal类中的构造函数相同的构造函数,并将其声明为非final。然后,我们在主函数中创建了一个Dog对象,并调用了它的方法来输出一条消息和设置其名称。由于Dog类中的构造函数与Animal类中的构造函数具有相同的参数列表和返回类型,因此编译器会选择调用Dog类中的构造函数来初始化其基类Animal对象的属性。

标签:27,name,Dog,Animal,override,final,类中,构造函数
From: https://www.cnblogs.com/codemagiciant/p/17524124.html

相关文章

  • 19C-19.16 ORA-17503 ORA-27300 ORA-27301 ORA-27302
    ***alter日志告警2023-07-01T02:05:13.474592+08:00Errorsinfile/u01/app/oracle/diag/rdbms/dg/dg1/trace/dg1_ora_17925.trc:ORA-17503:ksfdopn:2Failedtoopenfile+DATA/dg/PASSWORD/pwddgORA-27300:OSsystemdependentoperation:openfailedwithstatus:13ORA-......
  • classfinal加密java代码并且启动
    maven插件方式配置参数解释: 参数说明-file加密的jar/war完整路径-packages加密的包名(可为空,多个用","分割)-libjarsjar/war包lib下要加密jar文件名(可为空,多个用","分割)-cfgfiles需要加密的配置文件,一般是classes目录下的yml或propertie......
  • 2023年暑假集训总结/6.27
    6-27T1图一姬在一个n个点和m条边无向图中迷路了,她不知道她现在在哪里。每个点上有一个宝玉,一姬要收集k个宝玉才能缔结契约,走出这个无向图。图中被访问的点不能再访问第二次,经过每条边需要一定的时间,求所需的最大时间是多少?注:走到的点宝玉必须要取走。收集到k个宝......
  • 5727
    这道题用常规方法来做十分简单,但我选择用递归来做这道题。递归法依旧不难,但让代码优雅了很多,而且代码量很小。Code#include<iostream>usingnamespacestd;voidf(intn){ if(n!=1) if(n%2==0) f(n/2); else f(3*n+1); cout<<n<<'';}intmain(){intn;......
  • L27_用日语询问最美味的食物是什么
    语料的视频观看地址概述日语中询问从几样东西选哪个好,可以用:どれが一番~か的句式,比如どれが一番美味しいですか哪个最好吃どれが一番有名ですか哪个最有名どれが一番安いですか?哪个最便宜动画会话ご注文は?需要点什么?タムさん、何にする?Tam,你想吃什么?どれ......
  • LeetCode-Python-#27 移除元素
    题目描述给定一个数列nums和数值val,消除数列nums中与数值 val相同的元素,最终返回新数列的长度;要求:不能开辟空间分配新的数列,必须改变原输入nums数列;并对修改后的nums数列的元素顺序没有要求,可以被修改。Examplesnums=[3,2,2,3; val=3 则返回长度为2;nums=[0,1,2,2,3,0,4,2]......
  • finalshell连接超时的解决方法
    CentOS图形管理中的NetworkManager接管了网络配置,可以尝试执行以下命令恢复:systemctlstopNetworkManager临时关闭systemctldisableNetworkManager永久关闭网络管理命令systemctlstartnetwork.service开启网络服务然后在本机中再次使用ping命令,发现可以ping通虚拟机ip,这时......
  • 【算法题】2706. 购买两块巧克力
    题目:给你一个整数数组prices,它表示一个商店里若干巧克力的价格。同时给你一个整数money,表示你一开始拥有的钱数。你必须购买恰好两块巧克力,而且剩余的钱数必须是非负数。同时你想最小化购买两块巧克力的总花费。请你返回在购买两块巧克力后,最多能剩下多少钱。如果购买任意......
  • Kubernetes集群 v1.27.3
    基础环境三个节点均需操作,以k8s-master为例主机节点进程IP配置操作系统k8s-masterdocker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calicoNet:10.10.20.10Centos8-Streamk8s-worker01docker,kubelet,kube-proxy,calico......
  • 2023冲刺国赛模拟 27.1
    话说我的习惯是一套题全部改完后才写题解,然而上次的题解停留在\(20.1\),这足以看出近两日的颓废现状。由于昨天晚上做了个噩梦,所以今天的题解先扯点别的。目前初步鉴定噩梦是由FateZero中Caster的行为引起的。比较显然Caster及其御主都是以他人的痛苦为乐的人。在现代......