SQL去重查询C++ 中面向对象编程如何实现数据隐藏?C++ 中面向对象编程如何处理异常?Pimpl模式

news2024/12/14 8:17:43

SQL2 查询多列

select device_id,gender,age,university from user_profile;

SQL3 查询结果去重

select distinct university from user_profile;
select university from user_profile group by university;

C++ 中面向对象编程如何实现数据隐藏?

 使用访问控制修饰符:

private 访问控制
  • 在类中,将数据成员声明为private,这是实现数据隐藏的最常见方式。private成员只能在类的成员函数内部访问,外部代码(包括其他类和函数)无法直接访问这些成员。
protected 访问控制(用于继承场景)
  • protected成员在类内部可访问,在派生类中也可以访问,但对于外部代码是不可访问的。它主要用于在继承层次结构中,允许派生类访问基类的部分成员,但仍然隐藏这些成员不让外部直接访问。
Pimpl模式:

定义:Pimpl模式是指pointer to implementation。也就是说将类Widget的实现完全放到另外一个类Impl里,而类Widget对外提供接口,这些接口的调用最终会通过Impl指针成员(裸指针或智能指针),调用相应的实现接口。

具体实现:在头文件中只有一个私有成员变量pimpl指针,用户无法直接从头文件获取信息,起到了数据信息隐藏的作用

book.h

#pragma once
#include <iostream>

class impl;

class book
{
public:
	book();
	book(std::string, double);
	~book();
	/*私有成员为指针,禁止使用C++默认浅拷贝*/
	book(const book&) = delete;
	book& operator=(const book&) = delete;
	//移动拷贝构造
	book(book&&);
	book& operator=(book&&);

	void display();
private:
	std::unique_ptr<impl> pImpl;
};

 book.cpp

#include "book.h"

class impl
{
public:
	impl() {}
	impl(std::string name, double price);
	~impl();
	void display();
	void set_price(double);
	double get_price();
private:
	std::string book_name;
	double book_price;
};

impl::impl(std::string name, double price) :book_name(name), book_price(price)
{

}

impl::~impl()
{

}

void impl::display()
{
	std::cout << "book name:" << book_name << std::endl;
	std::cout << "book price:" << book_price << std::endl;
}

void impl::set_price(double price)
{
	book_price = price;
}

double
impl::get_price()
{
	return book_price;
}

book::book() :pImpl(std::make_unique<impl>())
{

}

book::book(std::string name, double price) : pImpl{ std::make_unique<impl>(name,price) }
{

}

book::~book() = default;

book& book::operator=(book&&) = default;

void book::display()
{
	pImpl->display();
}

 main.cpp

#include "book.h"

int main()
{
	book b("百年孤独", 100);
	b.display();
}

运行结果 

优势:这么做可以减少项目的依赖,进而减少不必要的编译。无法从头文件获取类的具体实现。

缺点:会在运行时增加开销,访问开销(对私有成员的每次访问都是用过指针间接访问的)、空间开销、生命周期管理开销,降低程序可读性。

 

C++ 中面向对象编程如何处理异常?

try - catch 块

  • C++ 使用try - catch块来捕获和处理异常。try块中放置可能会抛出异常的代码。当异常被抛出时,程序的控制权会转移到相应的catch块中。
       try {
           // 可能抛出异常的代码
           int dividend = 10;
           int divisor = 0;
           int result = dividend / divisor;
       } catch (const std::runtime_error& e) {
           // 处理runtime_error类型的异常
           std::cerr << "Runtime error: " << e.what() << std::endl;
       } catch (const std::exception& e) {
           // 处理其他类型的exception异常
           std::cerr << "General exception: " << e.what() << std::endl;
       } catch (...) {
           // 捕获所有其他类型的异常
           std::cerr << "An unknown exception occurred." << std::endl;
       }
  • 在这个例子中,尝试进行除法运算,当除数为 0 时,会抛出一个异常。try - catch块会捕获这个异常并进行相应的处理。
  • 异常类和层次结构
    • C++ 标准库提供了一系列的异常类,如std::exception是所有标准异常类的基类。它有许多派生类,如std::runtime_errorstd::logic_error等。
    • 可以自定义异常类,通过继承std::exception或其子类来实现。例如:
       class MyException : public std::runtime_error {
       public:
           MyException(const char* msg) : runtime_error(msg) {}
       };
  • 然后在代码中抛出和捕获这个自定义异常:
       try {
           // 假设某个条件触发异常抛出
           throw MyException("This is my custom exception.");
       } catch (const MyException& e) {
           std::cerr << "Caught my custom exception: " << e.what() << std::endl;
       }
  • 异常安全保证
    • 基本的异常安全保证包括:
      • 基本保证:如果异常被抛出,程序中的对象仍然保持在一个合理的状态。例如,在一个函数中,如果部分操作失败并抛出异常,对象不会处于一个被破坏的、无法使用的状态。
      • 强保证:函数要么完全成功,要么在抛出异常时将程序状态恢复到调用该函数之前的状态。这通常通过使用资源获取即初始化(RAII)技术来实现。例如,在构造函数中分配资源,如果构造失败,资源会被自动释放。
      • 不抛出保证(Nothrow guarantee):某些函数被保证不会抛出异常,例如一些简单的访问器函数(如get函数)可以设计为不抛出异常,以提供更可靠的行为。

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

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

相关文章

基于物联网的 AI 智能送药车与自维护基站系统研究

一、引言 &#xff08;一&#xff09;研究背景 随着科技的飞速发展&#xff0c;物联网技术在各个领域都展现出了巨大的潜力。在医疗领域&#xff0c;物联网技术的应用为提高医疗服务的效率和质量带来了新的机遇。其中&#xff0c;基于物联网的 AI 智能送药车与自维护基站系统…

sentinel 限流保护-笔记

本文属于b站图灵课堂springcloud笔记系列。讲的好还不要钱&#xff0c;值得推荐。 为什么要引入限流组件&#xff1f; 在微服务环境下&#xff0c;服务之间存在复杂的调用关系&#xff0c;单个服务的故障或过载可能会迅速影响到整个系统&#xff0c;导致服务雪崩效应。流控组件…

鸿蒙NEXT开发案例:颜文字搜索器

【引言】 本文将介绍一个名为“颜文字搜索器”的开发案例&#xff0c;该应用是基于鸿蒙NEXT平台构建的&#xff0c;旨在帮助用户快速查找和使用各种风格的表情符号。通过本案例的学习&#xff0c;读者可以了解如何在鸿蒙平台上进行数据处理、UI设计以及交互逻辑的实现。 【环…

【IntelliJ IDEA 集成工具】TalkX - AI编程助手

前言 在数字化时代&#xff0c;技术的迅猛发展给软件开发者带来了更多的挑战和机遇。为了提高技术开发群体在繁多项目中的编码效率和质量&#xff0c;他们需要一个强大而专业的工具来辅助开发过程&#xff0c;而正是为了满足这一需求&#xff0c;TalkX 应运而生。 一、概述 1…

python学opencv|读取图像(十二)BGR图像转HSV图像

【1】引言 前述已经学习了opencv中图像BGR相关知识&#xff0c;文章链接包括且不限于下述&#xff1a; python学opencv|读取图像&#xff08;六&#xff09;读取图像像素RGB值_opencv读取灰度图-CSDN博客 python学opencv|读取图像&#xff08;七&#xff09;抓取像素数据顺利…

Linux(网络协议和管理)

后面也会持续更新&#xff0c;学到新东西会在其中补充。 建议按顺序食用&#xff0c;欢迎批评或者交流&#xff01; 缺什么东西欢迎评论&#xff01;我都会及时修改的&#xff01; 在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频 王晓春老师的个人空间…

代码随想录训练营第十七天| 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

654.最大二叉树 题目链接/文章讲解&#xff1a; 代码随想录 视频讲解&#xff1a;又是构造二叉树&#xff0c;又有很多坑&#xff01;| LeetCode&#xff1a;654.最大二叉树_哔哩哔哩_bilibili 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子…

ISP(Image Signal Processor)——HDR技术总结

传统多帧融合技术 拍摄一系列不同曝光时长的图像帧&#xff08;LDR&#xff09;&#xff0c;然后使用融合算法进行融合成HDR图像。 融合算法可以分为两种 基于照度图估计的融合 基于照度估计需要拟合相机响应函数&#xff0c;详细可以参考如下论文&#xff1a; Recovering H…

【理想汽车中科院】基于模仿学习的端到端自动驾驶数据缩放规律

论文: https://arxiv.org/pdf/2412.02689 项目: https://github.com/ucaszyp/Driving-Scaling-Law 0. 摘要 端到端自动驾驶范式因其可扩展性而最近吸引了大量关注。然而&#xff0c;现有方法受到现实世界数据规模有限的制约&#xff0c;这阻碍了对端到端自动驾驶相关扩展规律…

程序的调试

一名优秀的程序员也是一名出色的侦探&#xff0c;每一次调试都是尝试破案的过程 前言 一、什么是调试&#xff1f; 二、调试 1.调试是什么 2.基本步骤 三、调试注意事项 1.怎么写出易于调试的代码 2.常见错误 总结 前言 主要是怎么调试&#xff0c;调试的注意事项&#xff0c…

Linux内核移植之内核简介

学到本章节&#xff0c;大家应该对Linux操作系统都有了一定的了解&#xff0c;但可能还不知道我们拿到手的内核源码都经历了什么。 linux有一个庞大的开源社区&#xff0c;每个人都可以向开源社区提交代码。由于linux内核十分庞大所以每个模块都有对应的维护人员。维护人员的工…

2024年鄂州初级、中级职称公示了

本次鄂州市工程、中职教师、技工学校教师、档案、农业、新闻、艺术、群文、文博等专业中级和初级职称公示了&#xff0c;通过共有371人&#xff0c;公示时间为2024年12月9日至2024年12月13日。 本次公示工程类中级职称人员有210人通过评审&#xff0c;助理职称有35人通过评审。…

node_modules文件夹删除失败解决办法

在前端开发过程中&#xff0c;node_modules 文件夹是一个必不可少的组成部分&#xff0c;里面存放着项目所需的各种依赖包。然而&#xff0c;随着项目的发展&#xff0c;node_modules 文件夹可能会变得异常庞大&#xff0c;甚至有时需要删除它来解决一些依赖冲突或清理空间。但…

【合作原创】使用Termux搭建可以使用的生产力环境(六)

前言 在上一篇【合作原创】使用Termux搭建可以使用的生产力环境&#xff08;五&#xff09;-CSDN博客我们讲到了如何美化xfce4桌面&#xff0c;达到类似于Windows的效果&#xff0c;这一篇将继续在上一篇桌面的基础上给我们的系统装上必要的软件&#xff0c;让它做到真正可以使…

40 list类 模拟实现

目录 一、list类简介 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;list与string和vector的区别 二、list类使用 &#xff08;一&#xff09;构造函数 &#xff08;二&#xff09;迭代器 &#xff08;三&#xff09;list capacity &#xff08;四&#x…

小程序开发常见问题

一、开发方案选择 1.小程序原生开发&#xff1a;需要live-player组件资质&#xff0c;对开发者的资质要求较高&#xff0c;开发难度较大&#xff1b; 2.小程序内嵌H5&#xff1a;因校验文档上限&#xff0c;目前平台已经不支持配置校验文件&#xff1b; 3.半屏小程序&#xff1…

02. Docker:安装和操作

目录 一、Docker的安装方式 1、实验环境准备 1.1 关闭防火墙 1.2 可以访问网络 1.3 配置yum源 2、yum安装docker 2.1 安装docker服务 2.2 配置镜像加速 2.3 启动docker服务 3、二进制安装docker 3.1 下载或上传安装包并解压 3.2 配置使用systemctl管理 3.3 配置镜像…

uniapp 开发小程序 准备工作

前言&#xff1a; 在本地使用vue2.0 实现网页版拍照功能&#xff0c;本地开发老是报错 NotFoundError: Requested device not found &#xff0c;原因是 浏览器主要用于处理网络协议&#xff08;如 HTTP、HTTPS&#xff09;相关的数据交互&#xff0c;它的运行环境被设计为相对…

vue3 封装request请求

vue3 原生请求封装 我这里用一个案例来解释 需求:把vue3原生的静态页 集成到 vue2 的若依项目 并且可以访问 vue2接口 在vue3 src 下的 utils 下 创建文件request.ts文件 import axios from "axios"; import { showMessage } from "./status"; // 引入状态…

Java安全—SpringBootActuator监控泄露Swagger自动化

前言 今天依旧是SpringBoot框架&#xff0c;估计还要一篇文章才能把它写完&#xff0c;没办法&#xff0c;Java安全的内容太多了。 Actuator SpringBoot Actuator模块提供了生产级别的功能&#xff0c;比如健康检查&#xff0c;审计&#xff0c;指标收集&#xff0c;HTTP跟踪…