c++ - 有没有办法在没有 .* 或 ->* 运算符的情况下调用成员函数

标签 c++ boost cdecl

以下通过指向成员函数的指针调用D::foo 函数的方法将产生错误:必须使用.*-> * 在 'f (...)' 中调用指向成员函数的指针 .. 当然这不是我们调用指向成员函数的指针的方式。

正确的调用方式是(d.*f)(5); OR (p->*f)(5);

我的问题是,'有没有办法在左侧没有类对象的情况下调用类的成员函数?我想知道我们是否可以将类对象 (this) 作为常规参数传递?

在我看来,归根结底(在汇编/二进制级别)一个类的所有成员函数都是普通函数,它们应该对 n + 1 个参数进行操作,其中(+1 用于 this )

如果我们在下面讨论 D::foo 函数,在汇编/二进制级别它应该对两个参数进行操作:

  1. 类对象本身(指向名为 this 的 D 类对象的指针)
  2. int

那么,有没有办法(或 hack)调用 D::foo 并将类对象作为函数参数传递给它,而不是使用 。或 -> 或 .* 或 ->* 类对象上的运算符?

示例代码:

#include <iostream>
using namespace std;

class D {
    public:
        void foo ( int a ) {
            cout << "D" << endl;
        }

        int data;
};


//typedef void  __cdecl ( D::*  Func)(int);
typedef void ( D::*  Func)(int);

int main ( void ) 
{
    D d;

    Func f = &D::foo;
    f(&d, 5);

    return 1;
 }

一种方法是使用 boost bind 即

(boost:: bind (&D::foo, &d, 5)) ();

编辑: “请注意,我不是在寻找该程序的有效版本,我知道如何使其有效”

最佳答案

您真的想在不使用 .-> 的情况下调用成员函数吗?真的,真的?嗯,好吧...

邪恶.h:

#ifdef __cplusplus
extern "C" {
#endif

struct MyStruct
{
#ifdef __cplusplus
    MyStruct();

    void method(int);
#endif
};

#ifdef __cplusplus
}
#endif

邪恶.cc:

#include <iostream>

#include "evil.h"

MyStruct::MyStruct() { std::cout << "This is MyStruct's constructor" << std::endl; }

void MyStruct::method(int i) { std::cout << "You passed " << i << std::endl; }

邪恶.c:

#include "evil.h"

int main()
{
    struct MyStruct my_struct;
    _ZN8MyStructC1Ev(&my_struct); /* MyStruct::MyStruct() */

    _ZN8MyStruct6methodEi(&my_struct, 3); /* MyStruct::method(int) */

    return 0;
}

这恰好适用于我在 Linux 上的 gcc 和 g++ 组合,但不用说它依赖于平台 ABI,并且在调用 underscore-capital letter 形式的函数时违反了 C89 标准.它几乎肯定不会与虚拟功能一起使用,我也不想尝试。这也可能是我写过的最邪恶的东西。但是还是……


编辑:引用OP:

In my mind, at end of the day (at assembly/binary level) all member functions of a class are normal functions which should operate on n + 1 arguments where (+1 is for this)

虽然自 CFront 以来的每个编译器确实都这样做了,但这只是一个实现细节。 C++ 标准竭力指定成员函数应该如何实现,而只是它们应该如何表现。

因为它是一个实现细节,所以不同的平台以不同的方式来实现它。这不仅仅是名称修改。例如,Linux 上使用的调用约定指定 this 作为第一个参数传递;其他实现(Borland、IIRC?)将 this 作为last 参数传递。

因此,如果您想将成员函数视为带有额外 this 的普通函数,那么您必须限制自己使用特定的 ABI。这篇文章提供了一个示例,说明您可以如何做到这一点(或者更确切地说,一个示例说明为什么您真的不应该这样做!)

so, is there a way (or hack) to call D::foo with class object passed to it as function argument instead of using . or -> or .* or ->* operators on class object?

特定于平台的、令人作呕的肮脏 hack...

关于c++ - 有没有办法在没有 .* 或 ->* 运算符的情况下调用成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19269438/

相关文章:

c++ - 你如何告诉 pyximport 使用 cython --cplus 选项?

c++ - C++中的抽象类声明

c - 你如何阅读 C 声明?

c++ - 将函数分配给具有相同签名但不同调用约定的 std::function 失败

c++ - 在 C++ 中,(int *) 和 & 有什么区别?

c++ - 使用 C++ AMP 库

c++ - 添加外部属性以包含图中顶点的索引( boost )

c++ - 带有 LD_PRELOAD 和 boost::interprocess 的 mmap() 不起作用

使用 g++ 4.6 和 boost::unordered_map 的 C++11 相关编译错误

c# - 为什么 Cdecl 调用在 "standard"P/Invoke 约定中经常不匹配?