我正在使用pimpl习语并想要引用前向声明类的一种方法.下面不是我正在做的,但使用相同的概念.
template< typename Class, void (Class::*Method)(void) > struct Call { Call( Class* c ) : m_c(c) { } void operator()( void ) { (m_c->*Method)(); } Class* m_c; }; class A { public: void foo( void ) { std::cout << "A::foo\n"; } }; // this works void do_foo( A* a ) { Call c(a); c(); } class B; // this doesn't compile extern void B::bar( void ); // this is what i'd ultimately like to do void do_bar( B* b ) { Call c(b); c(); }
两个问题:
可以这样做吗?
为什么不能这样做?
Johannes Sch.. 6
您无法转发声明成员函数.我认为原因是,当你在指向B的指针上调用函数时,编译器必须将this指针传递给该方法.但它还不知道B的精确类层次结构.因此,该指针的可能调整(例如,由于该方法是虚拟的)将是不可能的.编译器也不知道该方法具有什么可见性.毕竟,它可能是私人的,你不能从外面打电话.声明该成员函数的唯一方法是定义该类,然后在该定义中声明该函数.解决问题的另一种方法是声明你的自由函数:
class B; void do_bar( B* b );
然后在文件中定义do_bar,您可以在其中安全地包含类B的定义.
您无法转发声明成员函数.我认为原因是,当你在指向B的指针上调用函数时,编译器必须将this指针传递给该方法.但它还不知道B的精确类层次结构.因此,该指针的可能调整(例如,由于该方法是虚拟的)将是不可能的.编译器也不知道该方法具有什么可见性.毕竟,它可能是私人的,你不能从外面打电话.声明该成员函数的唯一方法是定义该类,然后在该定义中声明该函数.解决问题的另一种方法是声明你的自由函数:
class B; void do_bar( B* b );
然后在文件中定义do_bar,您可以在其中安全地包含类B的定义.