当前位置: 首页 > news >正文

牛客网 SQL1查询所有列

SQL1查询所有列

select id,device_id,gender,age,university,province from user_profile

每日问题

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

在C++中,面向对象编程(OOP)通过封装(Encapsulation)实现数据隐藏。封装是一种将对象的属性和行为(即数据成员和成员函数)组合在一起,并对外界隐藏其内部细节的机制。这样,对象的内部状态只能通过特定的成员函数(如getter和setter)来访问和修改,从而保护数据不被外部直接操作,确保数据的一致性和安全性。

以下是实现数据隐藏的关键步骤和示例:

1.使用访问控制符:

        public:成员可以从任何地方访问。

        private:成员只能在类内部访问。

        protected:成员在类内部和派生类中访问。

通常,数据成员被声明为private,而成员函数(尤其是用于访问和修改数据成员的函数)被声明为public。

2.使用getter和setter方法:

        Getter方法用于返回对象的数据成员的值。

        Setter方法用于设置对象的数据成员的值。

以下是一个简单的示例,展示了如何使用封装和访问控制符来实现数据隐藏:

#include <iostream>
#include <string>class Person {
private:std::string name; // 姓名int age;         // 年龄public:// 构造函数Person(const std::string& name, int age) : name(name), age(age) {}// 获取姓名std::string getName() const {return name;}// 设置姓名void setName(const std::string& name) {this->name = name;}// 获取年龄int getAge() const {return age;}// 设置年龄,包含简单验证void setAge(int age) {if (age >= 0) { // 年龄必须为非负数this->age = age;} else {std::cerr << "无效的年龄!" << std::endl;}}// 显示人员信息void display() const {std::cout << "姓名: " << name << ",年龄: " << age << std::endl;}
};int main() {Person person("Alice", 30);// 通过公共方法访问数据std::cout << "初始人员信息:" << std::endl;person.display();// 使用setter方法修改数据person.setName("Bob");person.setAge(25);// 通过公共方法访问修改后的数据std::cout << "修改后的人员信息:" << std::endl;person.display();// 尝试设置无效的年龄person.setAge(-5);// 再次显示以查看无效年龄是否设置成功std::cout << "尝试设置无效年龄后的人员信息:" << std::endl;person.display();return 0;
}

在这个示例中:

        name和age数据成员被声明为private,因此它们不能在类外部直接访问。

        getName和setName方法用于访问和修改name。

        getAge和setAge方法用于访问和修改age,并且setAge方法包含了一个简单的验证逻辑,确保年龄不能为负数。

        display方法用于输出对象的当前状态。

这样,通过封装和访问控制符,我们实现了数据隐藏,并确保了数据的安全性和一致性。

C++中多态性在实际项目中的场景应用有哪些?

C++中的多态性是面向对象编程(OOP)中非常重要的一个概念,它使得相同的接口能够有不同的实现,从而增强了代码的灵活性、可维护性和可扩展性。主要有两种类型:编译时多态性(通常是函数重载和运算符重载)和运行时多态性(通过虚函数实现)。在实际项目中,C++的多态性有很多应用场景,以下一些典型的例子:

1. GUI应用程序中的事件处理

在图形用户界面(GUI)开发中,事件处理是一个常见的应用场景。例如,假设你有不同类型的按钮、文本框和其他控件,它们都可能响应用户的点击事件或输入事件。你可以使用多态来创建一个通用的事件处理系统,基类定义一个事件处理接口(例如handleEvent()),而不同的控件类(按钮、文本框等)则分别提供具体的实现。

class Widget {
public:virtual void handleEvent() = 0;  // 纯虚函数virtual ~Widget() = default;
};class Button : public Widget {
public:void handleEvent() override {// 按钮点击事件的处理代码}
};class TextBox : public Widget {
public:void handleEvent() override {// 文本框输入事件的处理代码}
};

在运行时,你可以通过基类指针调用子类的handleEvent()方法,引用不同的控件类型来执行不同的逻辑。

2.插件架构与扩展性

插件架构是另一个常见的应用场景。在插件系统中,插件通常是通过基类接口来统一管理和调用的,不同的插件实现了相同的接口,可以根据实际需要在运行时动态加载和卸载。利用多态性可以轻松地添加新的插件,而不需要修改系统的核心代码。

class Plugin {
public:virtual void execute() = 0;virtual ~Plugin() = default;
};class PluginA : public Plugin {
public:void execute() override {// PluginA 的实现}
};class PluginB : public Plugin {
public:void execute() override {// PluginB 的实现}
};

通过基类指针或引用,您可以在不关心特定插件类型的情况下执行相应的插件逻辑。

3.动物层次结构

一个典型的例子是在动物类层次结构中使用多态。假设你要处理不同种类的动物,每个动物都有一个sound()方法。通过多态,基类Animal可以定义一个统一的接口,而每个子类根据具体的动物类型实现自己的声音。

class Animal {
public:virtual void sound() const = 0;virtual ~Animal() = default;
};class Dog : public Animal {
public:void sound() const override {std::cout << "Woof!" << std::endl;}
};class Cat : public Animal {
public:void sound() const override {std::cout << "Meow!" << std::endl;}
};

然后,通过基类指针或,你可以统一调用sound()方法,不需要引用具体是哪种动物。

void makeSound(const Animal& animal) {animal.sound();  // 多态性:调用具体子类的 sound() 方法
}int main() {Dog dog;Cat cat;makeSound(dog);  // 输出: Woof!makeSound(cat);  // 输出: Meow!
}

4.图形学应用中的Shape类

在图形学相关的项目中,经常需要处理各种形状(如圆形、形状、三角形等)。通过多态性,你可以创建一个统一的基类(例如Shape),并为每个具体的形状类提供相应的实现,比如计算面积、稀疏图形等操作。

class Shape {
public:virtual double area() const = 0;virtual void draw() const = 0;virtual ~Shape() = default;
};class Circle : public Shape {
private:double radius;
public:Circle(double r) : radius(r) {}double area() const override {return 3.14 * radius * radius;}void draw() const override {std::cout << "Drawing Circle" << std::endl;}
};class Rectangle : public Shape {
private:double width, height;
public:Rectangle(double w, double h) : width(w), height(h) {}double area() const override {return width * height;}void draw() const override {std::cout << "Drawing Rectangle" << std::endl;}
};

在实际项目中,你可以通过Shape类型的指针或引用来操作不同的形状对象,从而了解具体的形状类型。

5.支付系统

假设你有一个支付系统,可以处理不同的支付方式,如信用卡支付、宝支付、微信支付等。这些支付方式可以继承自一个基类PaymentMethod,并实现具体的支付逻辑。

class PaymentMethod {
public:virtual void processPayment(double amount) = 0;virtual ~PaymentMethod() = default;
};class CreditCard : public PaymentMethod {
public:void processPayment(double amount) override {std::cout << "Processing credit card payment of " << amount << std::endl;}
};class Alipay : public PaymentMethod {
public:void processPayment(double amount) override {std::cout << "Processing Alipay payment of " << amount << std::endl;}
};class WeChatPay : public PaymentMethod {
public:void processPayment(double amount) override {std::cout << "Processing WeChat payment of " << amount << std::endl;}
};

通过多态,您可以将不同的支付方式统一处理:

void processPayment(PaymentMethod* paymentMethod, double amount) {paymentMethod->processPayment(amount);
}int main() {CreditCard cc;Alipay alipay;WeChatPay wechatPay;processPayment(&cc, 100.0);processPayment(&alipay, 200.0);processPayment(&wechatPay, 300.0);
}

6.状态模式(State Pattern)

状态模式是一种行为设计模式,对象在内部状态改变时改变其行为。多态性在这种模式中应用得非常广泛。一个对象可以在多个状态之间切换,每个状态都实现了一个统一的接口。

class State {
public:virtual void handle() = 0;virtual ~State() = default;
};class ConcreteStateA : public State {
public:void handle() override {std::cout << "Handling state A" << std::endl;}
};class ConcreteStateB : public State {
public:void handle() override {std::cout << "Handling state B" << std::endl;}
};class Context {
private:State* state;
public:void setState(State* newState) {state = newState;}void request() {state->handle();}
};

总结

C++的多态性通过提供统一的接口和不同的实现,使得程序设计更加灵活、可扩展和可维护。在实际项目中,使用多态可以提高代码的复用性,简化维护工作,尤其是在需要时不同类型对象执行相同操作的场景中非常有用。

http://www.lryc.cn/news/504952.html

相关文章:

  • 【经验分享】OpenHarmony5.0.0-release编译RK3568不过问题(已解决)
  • 如何使用ERC404协议
  • 240004基于Jamva+ssm+maven+mysql的房屋租赁系统的设计与实现
  • ORACLE RAC ADG备库报错ORA-04021: timeout occurred while waiting to lock object
  • CAPL如何设置或修改CANoe TCP/IP协议栈的底层配置
  • git使用教程(超详细)-透彻理解git
  • 【2024 Dec 超实时】编辑安装llama.cpp并运行llama
  • Docker介绍、安装、namespace、cgroup、镜像-Dya 01
  • docker 搭建自动唤醒UpSnap工具
  • 3D一览通在线协同设计,助力汽车钣金件设计与制造数字化升级
  • 基于Matlab实现三维地球模型(源码)
  • 【Tomcat】第五站:Servlet容器
  • CTF 攻防世界 Web: FlatScience write-up
  • 【SpringBoot中MySQL生成唯一ID的常见方法】
  • 使用Flink CDC实现 Oracle数据库数据同步的oracle配置操作
  • c++作业7
  • vue 上传组件 vxe-upload 实现拖拽调整顺序
  • Windows 环境实战开源项目GFPGAN 教程
  • UE5 做简单的风景观光视频
  • k8s服务搭建与实战案例
  • JavaScript学习难点
  • Qt WORD/PDF(一)使用 QtPdfium库实现 PDF 预览
  • 解决创建laravel项目,使用国外镜像超时,国内镜像缺包的问题
  • Java泛型设计详解
  • 用ue5打开网址链接
  • 【大数据】-- 读放大和写放大
  • 【前端】JavaScript 抽取字符串特定部分题目详解与实现思路
  • CNCF云原生生态版图-分类指南(一)- 观测和分析
  • 热更新解决方案3 —— xLua
  • 如何让ai在游戏中更像一个人?