关于C++类中typedef函数的疑问

2024-04-05

我需要定义一个返回类对象的函数。

假设我有一个名为狗的类(.h 中的类声明和 .cpp 中的实现),当狗死时,我想调用一个函数让狗管理器知道这一点。在dog的SetFunc中我将收到要调用的函数:

Dog.h

class Dog
{
public:

    typedef void (*OndogDie)(Dog * dog);

    OndogDie function;

    void SetFunc(OndogDie func);
    void Die();
};

Dog.cpp

void Dog::SetFunc(Dog::OndogDie func)
{
    function = func;
}

void Dog::Die()
{
    function(this);
}

如果我将 typedef 放入 Dog 类中,则一切正常,但 Manager 类除外,它无法将 Dog 类的合适回调作为参数传递:

管理器.h

#include "Dog.h"

class Manager
{
public:
    Manager();
    void CbdogDie(Dog * dog);
};

管理器.cpp

void Manager::CbdogDie(Dog * d)
{
    //stuff
}

Manager::Manager()
{
    Dog d = Dog();
    d.SetFunc(CbdogDie); (Error: argument of type void(Manager::*)(Dog *d) is incompatible with parameter of type "Dog::OndogDie")
}

我已经查看了许多教程并回答了问题,但没有一个能帮助我找出代码的问题所在。我也考虑过使用委托类型,但它只适用于 clr 项目。

我认为问题可能出在我放置 typedef 函数的地方。还有其他地方可以定义这个函数吗?如果没有,有没有解决这个问题的方法,或者至少有替代方案。

Thanks


为了方便更多读者,重复我的评论:CbdogDie(在您的代码中)是一个函数成员(非静态)并且需要一个实例Manager被调用,因此其类型与您的回调不兼容typedef.

与您的错误无关,但仍然值得考虑:您不应该将调用回调的逻辑移至Dog的析构函数?在 C++ 中(例如,与 Java 不同),我们知道对象何时被破坏。

不确定您是否可以将其应用于实际问题,但这里有一些有效的示例。

#include <iostream>
#include <string>

class Dog
{
public:

  typedef void (* on_dog_die_callback_t)(const Dog&);

  Dog(const std::string& name, on_dog_die_callback_t callback) :
    name_(name), callback_(callback)
  {
    std::clog << "A new dog named " << this->getName() << " is born.\n";
  }

  ~Dog()
  {
    std::clog << "A dog named " <<  this->getName() << " has died.\n";
    if (this->callback_)  // allow NULL pointer for no-op
      this->callback_(*this);
  }

  std::string
  getName() const
  {
    return this->name_;
  }

private:

  std::string name_;
  on_dog_die_callback_t callback_;
};

// Note: This is a free function, not a class member.
void
friendly_callback(const Dog& dog)
{
  std::clog << "We are so sorry that " << dog.getName() << " died.\n";
}

struct Manager
{
  // Note: This is a static function.
  static void
  unfriendly_callback(const Dog& dog)
  {
    std::clog << "Haha, " << dog.getName() << " died.\n";
  }
};

int
main()
{
  Dog fido("Fido", friendly_callback);
  Dog leika("Leika", Manager::unfriendly_callback);
  Dog waldo("Waldo", 0);
}

运行这段代码的输出是:

A new dog named Fido is born.
A new dog named Leika is born.
A new dog named Waldo is born.
A dog named Waldo has died.
A dog named Leika has died.
Haha, Leika died.
A dog named Fido has died.
We are so sorry that Fido died.

请注意,我已经(不需要)更改了您的回调的签名以接受const参考一个Dog而不是指针。这通常被认为是更好的风格,但如果你need无论出于何种原因我看不到一个指针,你也可以做到。

Notice:如果您决定从析构函数调用回调,请注意需要注意一些不寻常的事情:

  • 在析构函数中尽早调用回调。如果你的Dog类拥有在调用回调之前在析构函数中释放的资源,您将传递一个this指向部分破坏的对象的指针并调用其上的任何成员函数可能会调用未定义的行为。
  • 回调不得调用任何virtual职能成员Dog它已经通过了。注意Dog的析构函数只会被调用after派生类的析构函数(如果有),因此它可以处理已经部分析构的对象。只要回调只对Dog基类,这很好,但是如果它尝试访问派生类的任何成员(通过virtual函数调用),将导致未定义的行为。

好消息:如果你的课程很简单(没有virtual函数,析构函数中没有显式释放资源),你会没事的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于C++类中typedef函数的疑问 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • C++ 中的软(不是:弱)引用 - 这可能吗?有实施吗?

    在 C 中我正在使用boost shared ptr and boost weak ptr自动删除不再需要的对象 我知道这些与引用计数一起工作 在 Java 中 内存由垃圾收集器管理 它将内置对象引用视为strong WeakReferen
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • ASP .NET MVC,创建类似路由配置的永久链接

    我需要帮助在 MVC 网站中创建类似 URL 路由的永久链接 Slug 已设置为 www xyz com profile slug 代码为 routes MapRoute name Profile url profile slug defa
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 使用 MID、LEN 和 FIND 函数提取单元格文本的某些部分?

    我有一份 Excel 作业 但我陷入了最后部分 我被要求使用 MID LEN 和 FIND 来提取单元格内的特定字符串 我非常了解每个人的工作方式 将这三者结合起来并让它们发挥作用是我遇到的问题 我需要将城市与地址的其余部分分开 然后将其显

随机推荐

  • 在client和serviceWorker之间传输数据

    我想尝试在 serviceWorker 中运行 websockets 我编写了注册serviceWorker的代码 if serviceWorker in navigator navigator serviceWorker register
  • SendInput 不会将基本 Unicode 发送到某些窗口

    我在 C 中遇到这个项目的问题 当使用 WinAPI SendInput 函数时
  • Excel VBA:为什么没有添加任何后续系列?

    我试图将大约 200 个系列绘制到一个图表上 并尝试使用 for 循环为我绘制所有系列 但是 当我运行以下代码时 只有第一个系列 不在 for 循环中 实际上进入了图表 for 循环生成的所有其他内容都没有显示 我不知道为什么 Sub Ma
  • 如何禁用/启用复选框激活中的 PayPal 按钮?

    我的网站上有一个页面设置为定期付款 但我想禁用 PayPal 结账按钮 直到有人选中同意我的服务条款的框 你能帮我弄清楚如何正确地做到这一点吗 谢谢 布拉德 p class hidden Please check the checkbox
  • httplib.InvalidURL:非数字端口:

    我正在尝试编写一个脚本来检查是否存在许多网址 import httplib with open urls txt as urls for url in urls connection httplib HTTPConnection url c
  • 我如何强制浮动 DIV 匹配另一个浮动 DIV 的高度?

    我的 HTML 代码只是将页面分为两列 分别为 65 35 div style width 65 height 1 background color FDD017 div div div div style width 35 height
  • @XmlPath 在 JAXB 编组期间没有影响

    我正在尝试使用创建 XMLJaxB Marshalling方法 我想跳过某些子项的父标签 或者可能添加新的XML某个元素的父标签 因此我尝试使用 XmlPath from import org eclipse persistence oxm
  • R plyr,data.table,应用data.frame的某些列

    我正在寻找加速我的代码的方法 我正在调查apply ply方法以及data table 不幸的是 我遇到了问题 这里有一个small样本数据 ids1 lt c 1 1 1 1 2 2 2 2 ids2 lt c 1 2 3 4 1 2 3
  • 如何在运行时更改android中睡眠/定时器线程的延迟?

    我试图做的是每次计数器变为 5 的倍数时减少计时器延迟 但是 一旦代码进入 if 块 它就停止递增计时器 我不明白发生了什么事 这是代码 thread new Thread public void run try if count 5 0
  • 最小化 WPF 中的窗口?

    使用 Windows 时如何以编程方式最小化窗口WPF 我似乎可以找到 Resize 属性 set WindowState WindowState Minimized
  • ListView 中重复的行

    我知道这个问题已经出现过很多次了 但由于某种原因我似乎无法让它发挥作用 事实上 在某些情况下 getView 会被多次调用 但是 在此处给出的示例中 http android amberfog com p 296 http android
  • 如何检查 python 函数是否发生更改(在实时代码中)?

    如果我有一个函数的引用 我可以检查它的代码对象f code 获取签名 然后针对此签名执行后续检查以查看代码是否已更改 这很好 但是 如果函数的依赖项之一发生变化怎么办 例如 def foo a b return bar a b 比方说foo
  • 我应该直接访问mongodb吗?

    我们正在制作android应用程序 需要从mongodb数据库获取数据 数据库中会有很多条目 并且请求会非常频繁 我们应该直接访问它还是制作一个 PHP 脚本来访问它并以 JSON 格式返回所需的结果 我们应该直接访问它吗 You 确实不想
  • 使用knitr和RStudio在外部文件中进行代码折叠

    我找不到任何方法可以将语法上可接受的 RStudio 样式折叠插入到外部 R 代码文件中 该文件设置为从 knitr 文档中使用 或者我错过了什么 有几种方法可以做到这一点 1 允许代码标头 例如 knitr Q1 也许 knitr Q1
  • java中如何对对象进行排序? [复制]

    这个问题在这里已经有答案了 可能的重复 如何按属性对对象的数组列表进行排序 https stackoverflow com questions 2535124 how to sort an arraylist of objects by a
  • 将行恢复为默认列值 mysql

    我正在使用 MySQL 社区服务器 5 1 有没有一种方法可以通过一个查询将所有行设置回默认列值 我刚刚添加了很多行 我为大多数指定的列设置了默认值 但由于某种原因 所有列值都设置为 0 我想知道是否有一个查询将所有列值设置为其默认值 并且
  • java.lang.IllegalStateException:找不到工厂javax.faces.application.ApplicationFactory的备份[重复]

    这个问题在这里已经有答案了 我想从 jsf 2 1 迁移到 2 2 但无法运行我的服务器 Tomcat 导致出现以下错误 我谨通知您 我在项目 Maven 中使用了 Hibernate Spring JSF Root WebApplicat
  • Windows 7 中 NASM 程序中的 I/O

    我想用 NASM 汇编语言进行编程 我有 NASM 2 07 和 Borland C 编译器 5 0 bcc32 我的操作系统是Windows 7 我不知道如何在Windows平台上使用NASM进行输入和输出 请问你能帮我吗 最简单的方法是
  • 调试 javascript 有哪些好的技巧? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 所以我相当经常地使用 JavaScr
  • 关于C++类中typedef函数的疑问

    我需要定义一个返回类对象的函数 假设我有一个名为狗的类 h 中的类声明和 cpp 中的实现 当狗死时 我想调用一个函数让狗管理器知道这一点 在dog的SetFunc中我将收到要调用的函数 Dog h class Dog public typ