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

news/2024/12/14 13:49:54/

SQL2 查询多列

sql">select device_id,gender,age,university from user_profile;

SQL3 查询结果去重

sql">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.ppmy.cn/news/1555030.html

相关文章

Electron electron-builder.yml 配置 (自定义包名,用户自定义安装目录...)

electron-builder.yml 配置 # 唯一的应用程序标识符&#xff0c;用于操作系统级别的识别 appId: com.electron.app# 应用程序的名称&#xff0c;显示在用户界面上 productName: 我的应用# 定义构建资源目录&#xff0c;放置图标、证书等资源文件 directories:buildResources: …

SpringCloudAlibaba教程之注册中心Nacos

目录 概念 架构 设计原则 架构分层 用户层 业务层 内核层 插件 单机部署 1.下载安装包 2.安装nacos 3.启动nacos 快速开始 1.添加Maven依赖 2.添加配置 3.启动 集群部署 搭建步骤 1.搭建数据库&#xff0c;初始化数据库表结构 2.配置nacos 3.启动nacos集群…

【ETCD】【源码阅读】深入解析 raftNode.start方法实现

让我们从源码层面逐步分析这段代码。这段代码是 ETCD Raft 实现中&#xff0c;raftNode 的 start 方法&#xff0c;负责启动一个 Raft 节点&#xff0c;并在一个新的 goroutine 中处理 Raft 相关的事件。以下是对代码的逐步分析&#xff1a; 代码总体结构 func (r *raftNode)…

数据结构——跳表

目录 1.什么是跳表-skiplist 2.skiplist的效率如何保证&#xff1f; 3.skiplist的实现 4.skiplist跟平衡搜索树和哈希表的对比 1.什么是跳表-skiplist skiplist本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是一样的…

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

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

重生之我在异世界学智力题(6)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言海盗分金币问题&#xff08;1&#x…

手机IP谜团:一个设备,两个IP?

在日常使用手机上网的过程中&#xff0c;有时我们会发现手机竟然显示了两个IP地址&#xff0c;这让人不禁感到困惑。那么&#xff0c;一个手机为何会出现两个IP呢&#xff1f;这背后究竟隐藏着什么原因&#xff1f;虎观代理小二将为您详细解析这一现象&#xff0c;并探讨其可能…

RK3576 Android14,内存大于4G时UVC应用无法申请内存

最近有个项目需要将Linux虚拟成UVC摄像头&#xff0c;开发过程中遇到一个奇怪的事情&#xff0c;通过V4l2框架接口申请内存时&#xff0c;相同的板子&#xff0c;只是内存一个4G一个8G。4G的内存可以申请成功&#xff0c;8G就不行。提示“内存不足” 内存更大反而内存不足&…