突破编程_C++_面试(基础知识(10))

面试题29:什么是嵌套类,它有什么作用

嵌套类指的是在一个类的内部定义的另一个类。嵌套类可以作为外部类的一个成员,但它与其声明类型紧密关联,不应被用作通用类型。嵌套类可以访问外部类的所有成员,包括私有成员,这是嵌套类的一个重要特性。
嵌套类的作用主要有以下几点:
(1)封装和隐藏实现细节:嵌套类可以用于隐藏实现细节,使得外部类看起来更加简洁和易于使用。
(2)提供服务:嵌套类通常是为外部类提供服务的,它可以访问外部类的所有成员,因此可以方便地实现与外部类相关的功能。
(3)代码组织:嵌套类可以用于组织代码,将相关的类放在一起,提高代码的可读性和可维护性。
需要注意的是,嵌套类不应被公开可见,除非必要。在设计良好的库中,开发人员几乎不需要使用嵌套类来实例化对象或声明变量。在大多数情况下,嵌套类应该被视为实现细节的一部分,而不是公开的 API 。
嵌套类访问权限遵循一般的类成员访问权限规则,嵌套类可以是 public 、 protected 或 private ,这取决于它们在外部类中的声明方式。这些访问修饰符决定了嵌套类在外部类的外部可见性和可访问性。
(1) public 嵌套类
如果嵌套类被声明为 public ,则它在外部类的外部是可见的,并且可以被任何能够访问外部类的代码所访问和使用。
(2) protected 嵌套类
如果嵌套类被声明为 protected ,则它在外部类的外部是不可见的,但可以被外部类的派生类访问。注意:一般很少将嵌套类定义成 protected 。
(3)Private嵌套类
如果嵌套类被声明为 private ,则它在外部类的外部是不可见的,并且只能被外部类的成员函数访问。
嵌套类在实现某些设计模式(如工厂模式、组合模式等)时也非常有用,典型的比如使用嵌套类实现工厂模式:

#include <iostream>  
#include <string>  using namespace std;// 外部类,作为工厂类的容器 
class AnimalFactory
{
public:// 嵌套类,定义不同的动物 class Animal{public:virtual void eat() {}};// 嵌套类,实现具体的动物类(猫)class Cat : public Animal{public:void eat() {printf("cat eat\n");}};// 嵌套类,实现具体的动物类(狗)class Dog : public Animal{public:void eat(){printf("dog eat\n");}};// 工厂方法,根据传入的字符串创建相应的动物  static std::shared_ptr<Animal> createAnimal(const std::string& animalType) {if ("Cat" == animalType) {return std::shared_ptr<Animal>(new Cat);}else if ("Dog" == animalType){return std::shared_ptr<Animal>(new Dog);}return nullptr; // 如果类型不匹配,返回空指针  }
};int main() 
{std::shared_ptr<AnimalFactory::Animal> cat = AnimalFactory::createAnimal("Cat");cat->eat();std::shared_ptr<AnimalFactory::Animal> dog = AnimalFactory::createAnimal("Dog");dog->eat();return 0;
}

上面代码的输出为:

cat eat
dog eat

在这个例子中,AnimalFactory 类包含了 3 嵌套类 Animal 、Cat 和 Dog,Cat 类和 Dog 类分别实现了 Animal 基类的 eat 方法。AnimalFactory 类还提供了一个静态工厂方法 createAnimal,该方法根据传入的字符串参数创建并返回相应类型的动物对象。main 函数中展示了如何使用工厂方法来创建和使用不同的对象。
使用嵌套类实现工厂模式的好处是,所有与形状相关的类都集中在 AnimalFactory 类中,这有助于保持代码的整洁和组织性。此外,通过将工厂方法放在 AnimalFactory 类中,可以确保只有这个类能够创建形状对象,这有助于控制对象的创建过程。

面试题30:什么是类静态成员,它有什么作用

类静态成员是类中声明为 static 的成员,包括静态成员变量和静态成员函数。静态数据成员是与类关联的全局变量,而不是与类的实例关联。静态成员函数可以在没有类实例的情况下调用,且只能访问静态成员变量或其他静态成员函数。
如下为类静态成员的样例:

#include <iostream> class MyClass
{
public:MyClass() {}~MyClass() {}public:static void printStaticVal(){printf("static value = %d\n", m_staticVal);}static void setStaticVal(int val){m_staticVal = val;}private:static int m_staticVal;
};int MyClass::m_staticVal = 0;int main() 
{MyClass::setStaticVal(1);MyClass::printStaticVal();return 0;
}

上面代码的输出为:

static value = 1

上面代码中, MyClass 有一个静态成员变量 m_staticVal 和两个静态成员函数 printStaticVal 和 setStaticVal 。这些静态成员可以被类的任何对象访问,也可以直接通过类名访问。当通过 MyClass::setStaticVal 设置 m_staticVal 的值时,所有 m_staticVal 的对象都会看到相同的值,因为静态成员是共享的。
类静态成员有如下 5 个特点:
(1)存储:静态数据成员在内存中只有一份拷贝,无论创建多少个类的对象。
(2)初始化:静态数据成员在类外部进行初始化,且只初始化一次。
(3)访问:静态成员函数只能访问静态数据成员或其他静态成员函数,不能访问非静态成员。
(4)生命周期:静态成员的生命周期与程序的生命周期相同。
(5)共享:所有类的实例共享同一个静态数据成员。
类静态成员的主要作用是提供类级别的信息或功能,这些信息或功能与类的具体实例无关。静态数据成员可以用于存储类级别的常量、统计信息或共享资源。静态成员函数可以用于执行不依赖于类实例的操作,如修改静态数据成员或执行与类相关的全局操作。此外,静态成员函数还可以用于访问静态数据成员,并在没有类实例的情况下被调用。

面试题31:什么是浅拷贝和深拷贝,其各自适用的场景是什么

浅拷贝( Shallow Copy ):只复制对象的值或对象的引用(指针),但不复制对象引用的实际对象。如果对象内部包含动态分配的内存或其他资源,则这些资源在浅拷贝后会被多个对象共享,可能导致资源释放时的错误(如双重删除)。浅拷贝适用于对象间共享资源且不需要修改这些资源的场景。浅拷贝可以提高性能,因为不需要复制大量数据。但是,如果共享的资源被意外修改或释放,可能会导致问题。
深拷贝( Deep Copy ):复制对象的值以及对象引用的实际对象。对于包含动态分配内存的对象,深拷贝会创建这些内存区域的新副本,确保每个对象都有自己独立的资源副本。深拷贝适用于需要对象拥有独立资源副本的场景。深拷贝可以确保每个对象都可以独立修改资源而不会影响其他对象。但是,深拷贝可能占用更多的内存,并且在复制大量数据时可能会影响性能。

面试题32:C++中默认的拷贝构造函数执行的是深拷贝还是浅拷贝

C++ 中默认的拷贝构造函数执行的是浅拷贝。它只逐成员复制对象的内容,如果成员是指针或引用,那么它只是复制这些指针或引用的值,而不是它们所指向的实际对象。

面试题33:如何在C++中实现深拷贝

要实现深拷贝,需要自定义拷贝构造函数与重载赋值运算符,并在其中为动态分配的内存或其他资源创建新的副本。如下为样例代码:

#include <iostream>  class MyClass 
{
public:MyClass(int value) {m_val = new int(value);}~MyClass() {delete m_val;}// 拷贝构造函数(深拷贝)  MyClass(const MyClass& other){m_val = new int(*(other.m_val));}// 赋值运算符(深拷贝)  MyClass& operator=(const MyClass& other){if (this != &other) {delete m_val; // 先删除当前对象的数据  m_val = new int(*(other.m_val)); // 然后复制其他对象的数据  }return *this;}public:void setVal(int val){*m_val = val;}void printVal(){printf("val = %d\n",*m_val);}private:int* m_val;
};int main() {MyClass obj1(0);MyClass obj2 = obj1;obj2.setVal(1);	// 通过 obj2 对象修改值,obj1 不会被改变printf("obj1: ");obj1.printVal();printf("obj2: ");obj2.printVal();return 0;
}

上面代码的输出为:

obj1: val = 0
obj2: val = 1

在上面代码中,拷贝构造函数和赋值运算符都创建了一个新的整数,并复制了 obj1 对象中 m_val 指针指向的值。这样,每个对象都有自己独立的内存块,修改一个对象不会影响另一个对象。
深拷贝通常比浅拷贝更耗时和资源密集,因为它涉及到分配额外的内存和复制数据。然而,深拷贝提供了更好的数据完整性和安全性,特别是在涉及到多个对象共享同一份数据时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/677929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

__init__.py的作用

__init__.py 是一个特殊的python文件。一个文件夹中有这一个文件时&#xff0c;那么这个文件夹就会被视作一个python包。 一般来说&#xff0c;__init__.py 这个文件是空的&#xff0c;但是它也可以用来配置下当前这个python包&#xff0c;如指定包的版本&#xff0c;或者控制…

《动手学深度学习(PyTorch版)》笔记8.4

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过&…

什么是Python中的上下文管理器(Context Managers)?with语句是如何工作的?请解释Python中的装饰器如何用于实现函数缓存。

在Python中&#xff0c;上下文管理器&#xff08;Context Managers&#xff09;是一种特殊的对象&#xff0c;它们定义了在执行with语句块之前和之后应该发生的行为。上下文管理器通常用于处理那些需要设置和清理的资源&#xff0c;例如文件打开/关闭、线程锁定/解锁、数据库连…

Qt 实现无边框窗口1.0

目录 项目需求&#xff1a; 1、没有边框&#xff1b; 2、点击windows系统的状态栏的程序运行图标可实现最大最小化&#xff1b; 3、可以移动窗口&#xff1b; 项目实现&#xff1a; 1、实现 无边框 2、实现 点击windows系统的状态栏的程序运行图标可实现最大最小化 3、实现 窗…

MongoDB存储引擎发展及WiredTiger深入解析(二)

在现代的数据管理领域中&#xff0c;MongoDB作为一个高性能、开源的NoSQL数据库系统&#xff0c;已经在全球范围内被广泛应用。而MongoDB背后的存储引擎&#xff0c;作为其数据管理的核心组件&#xff0c;也经历了不断的发展和优化。本文将对MongoDB的存储引擎发展进行简要回顾…

CVE-2021-42013 漏洞复现

CVE-2021-42013 漏洞版本&#xff1a;Apache 2.4.50 Apache版本2.4.50是对CVE-2021-&#xff08;版本2.4.49&#xff09;的修复&#xff0c;但是修复不完整导致可以绕过&#xff0c;从而产生了CVE-2021-42013&#xff08;版本2.4.50&#xff09;。 这时修复了对.%2e的检测。…

机器学习2--逻辑回归(案列)

糖尿病数据线性回归预测 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.datasets import load_diabetes diabetesload_diabetes() datadiabetes[data] targetdiabetes[target] feature_namesdiabetes[feature_names] data.shape df …

第66讲管理员登录功能实现

项目样式初始化 放assets目录下&#xff1b; border.css charset "utf-8"; .border, .border-top, .border-right, .border-bottom, .border-left, .border-topbottom, .border-rightleft, .border-topleft, .border-rightbottom, .border-topright, .border-botto…

Mac 远程 Linux 桌面 vnc

安装 vnc server su - yum install tigervnc-server -y创建连接用户&#xff0c; 也可以使用已经有的用户 useradd username13123cp /lib/systemd/system/vncserver.service /etc/systemd/system/vncserver:1.service配置文件 然后&#xff0c;我们需要在 /etc/systemd/syst…

华为机考入门python3--(9)牛客9-提取不重复的整数

分类&#xff1a;列表 知识点&#xff1a; 从右往左遍历每一个字符 my_str[::-1] 题目来自【牛客】 def reverse_unique(n): # 将输入的整数转换为字符串&#xff0c;这样可以从右向左遍历每一位 str_n str(n) # 创建一个空列表来保存不重复的数字 unique_digits []…

TS学习与实践

文章目录 学习资料TypeScript 介绍TypeScript 是什么&#xff1f;TypeScript 增加了什么&#xff1f;TypeScript 开发环境搭建 基本类型编译选项类声明属性属性修饰符getter 与 setter方法static 静态方法实例方法 构造函数继承 与 super抽象类接口interface 定义接口implement…

django中实现适配器模式

在Django中实现适配器模式&#xff08;Adapter Pattern&#xff09;涉及到创建一个适配器类&#xff0c;它允许不兼容的接口之间进行交互。适配器模式通常用于将一个类的接口转换为另一个客户端期望的接口。 一&#xff1a;实现例子 下面是一个简单的例子&#xff0c;演示如何…

C++笔记之regex(正则表达式)

C++笔记之regex(正则表达式) ——2024-02-10 ——《C++标准库》(第2版,侯捷译) Page 717 code review! 文章目录 C++笔记之regex(正则表达式)例1:使用正则表达式进行搜索(`std::regex_search`)例2:使用正则表达式进行全文匹配(`std::regex_match`)例3:使用正则表达式…

文件包含漏洞的应用与绕过技巧、防御方法

目录 包含日志文件 包含session 绕过技巧 指定前缀绕过 一、目录遍历 二、编码绕过 指定后缀绕过 一、利用URL 二、利用协议 三、长度截断 四、%00截断 文件包含漏洞防御 上一篇文章和大家介绍了一下文件包含漏洞和PHP伪协议的基本知识和利用PHP伪协议进行文件包含…

Java 内存区域介绍

&#xff08;1&#xff09;程序计数器 程序计数器主要有两个作用&#xff1a; 字节码解释器通过改变程序计数器来依次读取指令&#xff0c;从而实现代码的流程控制&#xff0c;如&#xff1a;顺序执行、选择、循环、异常处理。 在多线程的情况下&#xff0c;程序计数器用于记录…

VMware15 安装 Centos7后打开虚拟机,出现蓝屏问题处理

最方便的办法就是把虚拟机升级到最新版本--&#xff08;即vm版本问题&#xff09;

人类智能远远超越了物理与数理范畴

德国哲学家黑格尔曾这样写道&#xff0c;我们越是熟悉的东西&#xff0c;就越不清楚它。这或许意味着当我们对某个事物非常熟悉时&#xff0c;可能会陷入一种思维定势&#xff0c;导致我们无法客观地认识和理解它。这种思维定势可能来自于习惯、传统观念或者个人经验&#xff0…

牛客网 --- 送分题

题目描述 数据结构之神ccz又在出毒瘤数据结构了 神出了这样一个题&#xff1a; 给你三个数&#xff0c;在这三个数中间任意加*或者是&#xff0c;然后可以随便打括号&#xff0c;只要这个表达式合法 比如说1 2 3可以得到&#xff1a; 12*371*(23)51*2*36(12)*39 不能改变这三个…

计算机视觉主要知识点

计算机视觉是指利用计算机和算法来解析和理解图片和视频中的内容。这是一个跨学科领域&#xff0c;融合了计算机科学、图像处理、机器学习和模式识别等多方面的技术。以下是一些计算机视觉入门的基本知识点&#xff1a; 图像基础&#xff1a; 像素&#xff1a;图片的最基本组成…

《剑指 Offer》专项突破版 - 面试题 38、39 和 40 : 通过三道面试题详解单调栈(C++ 实现)

目录 面试题 38 : 每日温度 面试题 39 : 直方图最大矩形面积 方法一、暴力求解 方法二、递归求解 方法三、单调栈法 面试题 40 : 矩阵中的最大矩形 面试题 38 : 每日温度 题目&#xff1a; 输入一个数组&#xff0c;它的每个数字是某天的温度。请计算每天需要等几天才会…