C++笔记之两个类的实例之间传递参数的各种方法

news2024/11/25 2:34:55

C++笔记之两个类的实例之间传递参数的各种方法

code review!

文章目录

  • C++笔记之两个类的实例之间传递参数的各种方法
    • 1.构造函数参数传递
    • 2.成员函数参数传递
    • 3.友元函数
    • 4.友元类
    • 5.传递指针或引用
    • 6.静态成员变量
    • 7.静态成员函数
    • 8.全局变量或命名空间
    • 9.回调函数和函数指针
    • 10.观察者模式
    • 11.事件系统
    • 12.消息传递机制

1.构造函数参数传递

在这里插入图片描述

代码

class ClassA {
public:
    ClassA(int value) : memberA(value) {}
private:
    int memberA;
};

class ClassB {
public:
    ClassB(const ClassA& aInstance) : memberB(aInstance) {}
private:
    ClassA memberB;
};

int main() {
    ClassA objA(42);
    ClassB objB(objA);
    return 0;
}

2.成员函数参数传递

在这里插入图片描述

代码

class ClassA {
public:
    ClassA(int value) : memberA(value) {}
    int getValue() const { return memberA; }
private:
    int memberA;
};

class ClassB {
public:
    void doSomethingWithA(const ClassA& aInstance) {
        int value = aInstance.getValue();
        // 执行操作
    }
};

int main() {
    ClassA objA(42);
    ClassB objB;
    objB.doSomethingWithA(objA);
    return 0;
}

3.友元函数

在这里插入图片描述

代码

class ClassA;

class ClassB {
public:
    void printValue(const ClassA& objA);
};

class ClassA {
public:
    ClassA(int value) : aValue(value) {}

    friend void ClassB::printValue(const ClassA& objA);

private:
    int aValue;
};

void ClassB::printValue(const ClassA& objA) {
    std::cout << "Value from ClassA: " << objA.aValue << std::endl;
}

int main() {
    ClassA objA(42);
    ClassB objB;

    objB.printValue(objA);

    return 0;
}

4.友元类

在这里插入图片描述

代码

class ClassA;

class ClassB {
public:
    void printValue(const ClassA& objA);

    // Declare ClassA as a friend class
    friend class ClassA;
};

class ClassA {
public:
    ClassA(int value) : aValue(value) {}

    void setValue(int value) {
        aValue = value;
    }

private:
    int aValue;
};

void ClassB::printValue(const ClassA& objA) {
    std::cout << "Value from ClassA: " << objA.aValue << std::endl;
}

int main() {
    ClassA objA(42);
    ClassB objB;

    objB.printValue(objA);

    return 0;
}

5.传递指针或引用

在这里插入图片描述

代码

#include <iostream>

class ClassA {
public:
    ClassA(int value) : aValue(value) {}

    int getValue() const {
        return aValue;
    }

private:
    int aValue;
};

class ClassB {
public:
    void printValueByPointer(const ClassA* ptrA) {
        if (ptrA) {
            std::cout << "Value from ClassA using pointer: " << ptrA->getValue() << std::endl;
        } else {
            std::cout << "Invalid pointer to ClassA." << std::endl;
        }
    }

    void printValueByReference(const ClassA& refA) {
        std::cout << "Value from ClassA using reference: " << refA.getValue() << std::endl;
    }
};

int main() {
    ClassA objA(42);
    ClassB objB;

    // Passing pointer to ClassA
    objB.printValueByPointer(&objA); // Output: Value from ClassA using pointer: 42

    // Passing reference to ClassA
    objB.printValueByReference(objA); // Output: Value from ClassA using reference: 42

    return 0;
}

6.静态成员变量

在这里插入图片描述

代码

class ClassA {
public:
    static int sharedValue;
};

class ClassB {
public:
    void printSharedValue() {
        std::cout << "Shared Value: " << ClassA::sharedValue << std::endl;
    }
};

int ClassA::sharedValue = 42;

int main() {
    ClassB objB;
    objB.printSharedValue();

    return 0;
}

7.静态成员函数

在这里插入图片描述

代码

#include <iostream>

class SharedInfo {
public:
    static int getValue() {
        return sharedValue;
    }

    static void setValue(int value) {
        sharedValue = value;
    }

private:
    static int sharedValue;
};

// Initialize the static member
int SharedInfo::sharedValue = 0;

class ClassA {
public:
    void printSharedValue() {
        std::cout << "Shared Value from ClassA: " << SharedInfo::getValue() << std::endl;
    }
};

class ClassB {
public:
    void modifySharedValue() {
        SharedInfo::setValue(100);
    }
};

int main() {
    ClassA objA;
    ClassB objB;

    objA.printSharedValue();
    objB.modifySharedValue();
    objA.printSharedValue();

    return 0;
}

8.全局变量或命名空间

在这里插入图片描述

代码

namespace MyNamespace {
    int sharedValue = 42;
}

class ClassA {
public:
    void printSharedValue() {
        std::cout << "Shared Value: " << MyNamespace::sharedValue << std::endl;
    }
};

class ClassB {
public:
    void modifySharedValue() {
        MyNamespace::sharedValue = 100;
    }
};

int main() {
    ClassA objA;
    ClassB objB;

    objA.printSharedValue();
    objB.modifySharedValue();
    objA.printSharedValue();

    return 0;
}

9.回调函数和函数指针

在这里插入图片描述

代码

#include <iostream>

// Callback function type
typedef void (*CallbackFunction)(int);

class ClassA {
public:
    ClassA(int value) : aValue(value) {}

    void performCallback(CallbackFunction callback) {
        callback(aValue);
    }

private:
    int aValue;
};

class ClassB {
public:
    static void printValue(int value) {
        std::cout << "Value from ClassA: " << value << std::endl;
    }
};

int main() {
    ClassA objA(42);
    
    // Passing callback function using function pointer
    objA.performCallback(ClassB::printValue); // Output: Value from ClassA: 42

    return 0;
}

10.观察者模式

可以使用观察者模式在C++中在两个类的实例之间传递参数。观察者模式用于在一个对象的状态发生变化时,自动通知和更新其他相关对象。以下是一个使用观察者模式的示例,并提供运行结果:

#include <iostream>
#include <vector>

class Observer;  // Forward declaration

class Subject {
public:
    void addObserver(Observer* observer) {
        observers.push_back(observer);
    }

    void removeObserver(Observer* observer) {
        observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
    }

    void notify(int value) {
        for (Observer* observer : observers) {
            observer->update(value);
        }
    }

private:
    std::vector<Observer*> observers;
};

class Observer {
public:
    virtual void update(int value) = 0;
};

class ClassA : public Observer {
public:
    void attachToSubject(Subject* subject) {
        subject->addObserver(this);
    }

    void detachFromSubject(Subject* subject) {
        subject->removeObserver(this);
    }

    void update(int value) override {
        std::cout << "ClassA received update: " << value << std::endl;
    }
};

int main() {
    Subject subject;
    ClassA objA1, objA2;

    objA1.attachToSubject(&subject);
    objA2.attachToSubject(&subject);

    subject.notify(42); // Output: ClassA received update: 42 \n ClassA received update: 42

    objA1.detachFromSubject(&subject);
    subject.notify(100); // Output: ClassA received update: 100

    return 0;
}

在这个示例中,我们首先定义了一个Subject类,它维护一个观察者列表并提供添加、删除和通知观察者的功能。然后,我们定义了一个Observer类,其中包含一个抽象的update函数,用于接收主题的通知。

ClassA类继承自Observer类,实现了update函数。在main()函数中,我们创建了一个Subject对象和两个ClassA对象。然后,我们将两个ClassA对象附加到Subject对象,并调用subject.notify(42)通知观察者更新。这导致两个ClassA对象都收到了相同的更新。

接着,我们将一个ClassA对象从Subject对象分离,并再次调用subject.notify(100)。这次只有一个ClassA对象收到了更新。

运行结果将是:

ClassA received update: 42
ClassA received update: 42
ClassA received update: 100

这个例子演示了如何使用观察者模式在两个类的实例之间传递参数,其中一个类充当主题(Subject),而另一个类充当观察者(Observer)。当主题的状态发生变化时,通知所有观察者进行更新。

11.事件系统

在 C++ 中,没有内置的事件系统,但你可以模拟一个简单的事件系统来在两个类的实例之间传递参数。这可以通过函数指针、回调函数或者 C++11 中的 std::function 和 std::bind 来实现。以下是一个使用 std::function 和 std::bind 模拟事件系统的示例,并提供运行结果:

#include <iostream>
#include <functional>

class Event {
public:
    void subscribe(std::function<void(int)> callback) {
        subscribers.push_back(callback);
    }

    void unsubscribe(std::function<void(int)> callback) {
        subscribers.remove(callback);
    }

    void notify(int value) {
        for (auto& callback : subscribers) {
            callback(value);
        }
    }

private:
    std::list<std::function<void(int)>> subscribers;
};

class ClassA {
public:
    ClassA(Event* event) : event(event) {}

    void triggerEvent(int value) {
        event->notify(value);
    }

private:
    Event* event;
};

class ClassB {
public:
    void handleEvent(int value) {
        std::cout << "ClassB received event: " << value << std::endl;
    }
};

int main() {
    Event event;
    ClassA objA(&event);
    ClassB objB;

    // Subscribe ClassB's handleEvent to the event
    event.subscribe(std::bind(&ClassB::handleEvent, &objB, std::placeholders::_1));

    objA.triggerEvent(42); // Output: ClassB received event: 42

    // Unsubscribe ClassB's handleEvent from the event
    event.unsubscribe(std::bind(&ClassB::handleEvent, &objB, std::placeholders::_1));

    objA.triggerEvent(100);

    return 0;
}

在这个示例中,我们首先定义了一个简单的事件类 Event,它允许订阅者(函数)通过 subscribe 方法订阅事件,通过 unsubscribe 方法取消订阅,然后通过 notify 方法通知所有订阅者。接着,我们定义了两个类 ClassAClassBClassA 有一个触发事件的方法 triggerEvent,它会通知事件对象。ClassB 有一个处理事件的方法 handleEvent

main() 函数中,我们创建了一个 Event 对象和一个 ClassA 对象。然后,我们使用 event.subscribe 方法将 ClassB::handleEvent 方法绑定到事件上,从而订阅了事件。接着,我们调用 objA.triggerEvent(42) 来触发事件,这会导致 ClassBhandleEvent 方法被调用。

接着,我们使用 event.unsubscribe 方法取消订阅 ClassB::handleEvent 方法,然后再次调用 objA.triggerEvent(100),但因为已经取消了订阅,所以 ClassBhandleEvent 方法不会再被调用。

运行结果将是:

ClassB received event: 42

这个例子演示了如何模拟一个简单的事件系统,在两个类的实例之间传递参数。在本例中,ClassA 充当事件的触发器,ClassB 充当事件的订阅者。

12.消息传递机制

在 C++ 中,使用消息传递机制来在两个类的实例之间传递参数可以通过使用事件系统、消息队列、观察者模式等方式来实现。下面是一个使用简单的事件系统模拟消息传递机制的示例,并提供运行结果:

#include <iostream>
#include <functional>
#include <list>

class Message {
public:
    Message(int value) : data(value) {}

    int getData() const {
        return data;
    }

private:
    int data;
};

class EventBus {
public:
    static EventBus& getInstance() {
        static EventBus instance;
        return instance;
    }

    void publish(const Message& message) {
        for (auto& subscriber : subscribers) {
            subscriber(message);
        }
    }

    void subscribe(std::function<void(const Message&)> callback) {
        subscribers.push_back(callback);
    }

private:
    EventBus() {}

    std::list<std::function<void(const Message&)>> subscribers;
};

class ClassA {
public:
    ClassA() {
        EventBus::getInstance().subscribe(std::bind(&ClassA::handleMessage, this, std::placeholders::_1));
    }

    void sendMessage(int value) {
        Message message(value);
        EventBus::getInstance().publish(message);
    }

    void handleMessage(const Message& message) {
        std::cout << "ClassA received message with data: " << message.getData() << std::endl;
    }
};

class ClassB {
public:
    void handleMessage(const Message& message) {
        std::cout << "ClassB received message with data: " << message.getData() << std::endl;
    }
};

int main() {
    ClassA objA;
    ClassB objB;

    Message message(42);
    objA.sendMessage(message); // Output: ClassA received message with data: 42

    EventBus::getInstance().subscribe(std::bind(&ClassB::handleMessage, &objB, std::placeholders::_1));
    objA.sendMessage(100); // Output: ClassA received message with data: 100 \n ClassB received message with data: 100

    return 0;
}

在这个示例中,我们定义了一个 Message 类,表示传递的消息。然后,我们创建了一个简单的事件总线 EventBus,它允许订阅者通过 subscribe 方法订阅消息,并通过 publish 方法发布消息。ClassAClassB 分别作为消息的发送者和接收者。在 main() 函数中,我们创建了一个 ClassA 对象和一个 ClassB 对象,然后通过事件总线来传递消息。

在运行结果中,你将看到消息被成功传递并在接收者类中处理:

ClassA received message with data: 42
ClassA received message with data: 100
ClassB received message with data: 100

这个例子演示了如何使用简单的事件系统来模拟消息传递机制,在两个类的实例之间传递参数。

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

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

相关文章

【第五章 flutter学习之flutter进阶组件-上篇】

文章目录 一、列表组件1.常规列表2.动态列表 二、FridView组件三、Stack层叠组件四、AspectRatio Card CircleAvatar组件五、按钮组件六、Stack组件七、Wrap组件八、StatefulWidget有状态组件总结 一、列表组件 1.常规列表 children: const <Widget>[ListTile(leading: …

喀麦隆ECTN(BESC)申请流程

据CAMEROON喀麦隆法令&#xff0c;所有发货至喀麦隆的货物都必须申请ECTN(BESC)电子货物跟踪单。如果没有申请&#xff0c;将被视为触犯喀麦隆的条例&#xff0c;并在目的港受到严厉惩罚。ECTN是英语ELECTRONIC CARGO TRACKING NOTE的简称&#xff1b;BESC是法语BORDEREAU ELEC…

开关电源控制--bode图相角裕量的选择

什么是相角裕量 在Bode图中&#xff0c;相角裕量是指系统的相位裕量&#xff0c;用于评估系统的稳定性和频率响应特性。 Bode图是一种常用的频率响应图&#xff0c;将系统的增益和相位随频率变化的情况绘制出来。在Bode图中&#xff0c;相角裕量表示系统的相位与-180度&#…

ensp与虚拟机搭建测试环境

1.虚拟机配置 ①首先确定VMnet8 IP地址&#xff0c;若要修改IP地址&#xff0c;保证在启动Ensp前操作 ②尽量保证NAT模式 2.ensp配置 (1)拓扑结构 (2)Cloud配置 ①首先点击 绑定信息 UDP → 增加 ②然后点击 绑定信息 VMware ... → 增加 ③最后在 端口映射设置上点击双向通…

编译工具:CMake(二)| 最简单的实例[构建、解析、外部构建]

编译工具&#xff1a;CMake&#xff08;二&#xff09;| 最简单的实例[构建、解析、外部构建] 编写代码与文件构建工程解析PROJECT 指令的语法是&#xff1a;SET 指令的语法是&#xff1a;MESSAGE 指令的语法是&#xff1a;ADD_EXECUTABLE 指令${} 指令 外部构建 # 前言 按照程…

github 无语的问题,Host does not existfatal: Could not read from remote repository.

Unable to open connection: Host does not existfatal: Could not read from remote repository. image.png image.png image.png Please make sure you have the correct access rights and the repository exists. 如果github desktop和git pull 和git clone全部都出问题了&…

ebay儿童书包产品CPC认证

儿童书包是一种能够盛放书本或者文具的包。现在的书包五花八门&#xff0c;以普通的布料或者是帆布等制成&#xff0c;有背带&#xff0c;包内一般分栏。一般分三种&#xff0c;背在身后的&#xff0c;挎在肩上的&#xff0c;轮式&#xff08;可以拖行&#xff09;的。 一、美国…

探索未来:直播实时美颜SDK在增强现实(AR)直播中的前景

在AR直播中&#xff0c;观众可以与虚拟元素实时互动&#xff0c;为用户带来更加丰富、沉浸式的体验。那么&#xff0c;直播美颜SDK在AR中有哪些应用呢&#xff1f;下文小编将于大家一同探讨美颜SDK与AR有哪些关联。 一、AR直播与直播实时美颜SDK的结合 增强现实技术在直播中…

使用C#的窗体显示与隐藏动画效果方案 - 开源研究系列文章

今天继续研究C#的WinForm的显示动画效果。 上次我们实现了无边框窗体的显示动画效果(见博文&#xff1a;基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章 )&#xff0c;这次介绍的是未在任务栏托盘中窗体的显示隐藏动画效果的实现代码。 1、 项目目录&#xff1b…

(03)Unity HTC VRTK 基于 URP 开发记录

1.简介 本篇主要内容为&#xff1a;URP如何与VRTK结合、URP需要注意的地方、VRTK的功能进行阐述。 因项目本身要求要渲染出比较好的画质&#xff0c;所以抛弃了Unity默认渲染管线Built-in&#xff0c;使用URP进行渲染&#xff0c;当然也可以选HDRP&#xff0c;但考虑到后期项目…

STM32 4G学习(二)

特性参数 ATK-IDM750C是正点原子开发的一款高性能4G Cat1 DTU产品&#xff0c;支持移动4G、联通4G和电信4G手机卡。 它以高速率、低延迟和无线数传作为核心功能&#xff0c;可快速解决应用场景下的无线数传方案。 它支持TCP/UDP/HTTP/MQTT/DNS/RNDIS/NTP协议&#xff0c;支持…

第八篇: K8S Prometheus Operator实现Ceph集群企业微信机器人告警

Prometheus Operator实现Ceph集群企业微信告警 实现方案 我们的k8s集群与ceph集群是部署在不同的服务器上&#xff0c;因此实现方案如下&#xff1a; (1) ceph集群开启mgr内置的exporter服务&#xff0c;用于获取ceph集群的metrics (2) k8s集群通过 Service Endponit Ser…

Nacos源码 (2) 核心模块

返回目录 整体架构 服务管理&#xff1a;实现服务CRUD&#xff0c;域名CRUD&#xff0c;服务健康状态检查&#xff0c;服务权重管理等功能配置管理&#xff1a;实现配置管CRUD&#xff0c;版本管理&#xff0c;灰度管理&#xff0c;监听管理&#xff0c;推送轨迹&#xff0c;聚…

计算机组成原理-笔记-第一章

目录 一、第一章——计算机系统概述&#xff08;硬件软件&#xff09; 1、计算机发展 &#xff08;1&#xff09;小结 2、硬件的基本组成&#xff08;冯诺依曼机&#xff09; &#xff08;1&#xff09;冯诺依曼机——运算器为中心 &#xff08;2&#xff09;现代计算器结…

微服务 云原生:搭建 Harbor 私有镜像仓库

Harbor官网 写在文前&#xff1a; 本文中用到机器均为虚拟机 CentOS-7-x86_64-Minimal-2009 镜像。 基础设施要求 虚拟机配置达到最低要求即可&#xff0c;本次系统中使用 docker 24.0.4、docker-compose 1.29.2。docker 及 docker-compose 的安装可以参考上篇文章 微服务 &am…

《HeadFirst设计模式(第二版)》第七章代码——适配器模式

代码文件目录&#xff1a; Example1: Duck package Chapter7_AdapterAndFacadePattern.Adapter.Example1;/*** Author 竹心* Date 2023/8/7**/public interface Duck {public void quack();public void fly(); }DuckTestDrive package Chapter7_AdapterAndFacadePattern.Ada…

Vue2源码分析-day1

初始化数据 vue中最核心的我们都知道那就是响应式数据&#xff0c;数据的变化视图自动更新。那么我们来new一个我们自己的vue 在index.html文件下加入如下代码&#xff0c;这也是vue最常见的基本结构。data已经有了下面我们来获取data的数据 <script src"./vue.js&qu…

怎么快速搭建BI?奥威BI系统做出了表率

搭建BI系统有两大关键&#xff0c;分别是环境搭建和数仓建设。这两点不管是哪一个都相当地费时费力&#xff0c;那要怎么才能快速搭建BI平台&#xff0c;顺利实现全企业数字化运营决策&#xff1f;奥威BI系统方案&#xff0c;你值得拥有&#xff01; 奥威BI系统方案&#xff0…

VS+Qt环境下解决中文乱码问题

目录 原因解决方案总结 原因 使用VSQt出现中文乱码的情况一般都是给控件添加中文文本时出现&#xff0c;而控件需要的字符串类型是QString&#xff0c;默认是utf-8。在 Visual Studio 中&#xff0c;源代码文件的默认执行字符集可能是 Windows 默认的 ANSI 字符集&#xff0c;…

0基础学习VR全景平台篇 第79篇:全景相机-泰科易如何直播推流

泰科易科技是中国的一家研发全景相机的高科技公司&#xff0c;前不久&#xff0c;在2020世界VR产业大会上发布了新一代5G VR直播影像采集终端--360starlight。以其出色的夜景成像效果和一“部”到位的直播方案重新定义了VR慢直播相机&#xff0c;对行业具有高度借鉴意义。 本文…