当前位置:  开发笔记 > 编程语言 > 正文

为什么C++没有指向成员函数类型的指针?

如何解决《为什么C++没有指向成员函数类型的指针?》经验,为你挑选了2个好方法。

我在这里完全错了,但据我所知,C++并没有真正的"成员函数指针"类型.我知道你可以使用Boost和mem_fun等做一些技巧.但是为什么C++的设计者决定不使用包含指向函数的指针的64位指针和指向对象的指针?

我的意思是指向未知类型特定对象的成员函数的指针.IE可以用来回调的东西.这将是一个包含两个值的类型.第一个值是指向函数的指针,第二个值是指向对象的特定实例的指针.

我不是指一个指向类的一般成员函数的指针.例如

int (Fred::*)(char,float)

它本来是如此有用,让我的生活更轻松.

雨果



1> Aaron..:

@RocketMagnet - 这是对你的另一个问题的回应,那个被标记为重复的问题.我正在回答这个问题,而不是这个问题.

通常,C++指向成员函数的指针不能在类层次结构中进行转换.那说你经常可以逃脱它.例如:

#include 
using std::cout;
class A { public: int x; };
class B { public: int y; };
class C : public B, public A { public: void foo(){ cout << "a.x == " << x << "\n";}};

int main() {
    typedef void (A::*pmf_t)();
    C c; c.x = 42; c.y = -1;

    pmf_t mf = static_cast(&C::foo);
    (c.*mf)();
}

编译此代码,编译器正确地抱怨:

$ cl /EHsc /Zi /nologo pmf.cpp
pmf.cpp
pmf.cpp(15) : warning C4407: cast between different pointer to member representations, compiler may generate incorrect code

$

那么回答"为什么C++没有指向成员函数的指针 - 函数在void-class?" 是这个想象中的基类 - 所有东西都没有成员,所以没有任何价值可以安全地分配给它!"void(C :: )()"和"void(void ::)()"是互不兼容的类型.

现在,我打赌你在考虑"等等,我之前已经投出了成员函数指针!" 是的,您可以使用reinterpret_cast和单继承.这与其他重新解释演员阵营属于同一类别:

#include 
using std::cout;
class A { public: int x; };
class B { public: int y; };
class C : public B, public A { public: void foo(){ cout << "a.x == " << x << "\n";}};
class D { public: int z; };

int main() {
    C c; c.x = 42; c.y = -1;

    // this will print -1
    D& d = reinterpret_cast(c);
    cout << "d.z == " << d.z << "\n";
}

所以,如果void (void::*)()确实存在,但没有什么可以安全/可移植地分配给它.

传统上,你可以在void (*)(void*)任何你使用的地方使用签名函数void (void::*)(),因为虽然成员函数指针在继承层次上不能很好地投射,但是void指针确实很好.代替:

#include 
using std::cout;
class A { public: int x; };
class B { public: int y; };
class C : public B, public A { public: void foo(){ cout << "a.x == " << x << "\n";}};

void do_foo(void* ptrToC){
    C* c = static_cast(ptrToC);
    c->foo();
}

int main() {
    typedef void (*pf_t)(void*);
    C c; c.x = 42; c.y = -1;

    pf_t f = do_foo;
    f(&c);
}

所以对你的问题.为什么C++不支持这种类型的转换.指向成员函数类型的指针已经必须处理虚拟和非虚拟基类,以及虚拟和非虚拟成员函数,它们都在同一类型中,在某些平台上将它们扩展为4*sizeof(void*).我认为因为它会使指针到成员函数的实现更加复杂,并且原始函数指针已经很好地解决了这个问题.

像其他人评论的那样,C++为图书馆编写者提供了足够的工具来完成这项工作,然后像你我这样的"普通"程序员应该使用这些库而不是冒出这些细节.

编辑:标记社区维基.请仅编辑以包含对C++标准的相关引用,并添加斜体.(尤其是在我理解错误的地方添加对标准的引用!^ _ ^)



2> 小智..:

正如其他人所指出的,C++确实有一个成员函数指针类型.

你正在寻找的术语是"绑定功能".C++没有为函数绑定提供语法糖的原因是因为它的哲学只提供了最基本的工具,然后你可以用它来构建你想要的所有工具.这有助于保持语言"小"(或至少,令人难以置信的巨大).

类似地,C++没有像C#那样的lock {}原语,但是它有RAII,由boost的scoped_lock使用.

当然,思想学派说你应该为可能有用的一切添加语法糖.无论好坏,C++都不属于那所学校.

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有