所以我现在处于一种两难境地。我想制作一个函数指针,但我想把它变成一个虚函数。不一定是虚函数本身,而是衍生的函数。我试过制作指针,但函数需要是静态的。当我尝试创建静态虚函数时,编译器会对我大喊大叫。我也不想让函数指针类具体,所以可以想象其他类可以使用指针。这就是我在伪代码中的意思:
class C
{
public:
virtual void something();
};
class B : public C
{
public:
void something();
};
class D
{
public:
void something();
};
int main()
{
void(*pointer)();
B b;
D d;
pointer = b.something.
pointer();
pointer = d.something;
pointer()
}
某些东西不是静态方法,但我希望指针能够指向它。指针也可以指向其他非静态的类方法。我有什么可以做的吗?
修改 我终于能够弄清楚如何做到这一点。我不得不使用std :: function。这也适用于常规成员函数,不一定是虚函数。这是它的样子:
class A
{
public:
virtual void something(int i);
};
class B
{
virtual void somethingElse(int i);
}
//This isn't needed, it just saves typing if you have multiple pointers
typedef std::function<void(int)> functionType
functionType* pointer;
int main()
{
B b;
A a;
pointer = std::bind(&A::something,&a,std::placeholders::_1);
pointer(1)
pointer = std::bind(&B::somethingElse,&b,std::placeholders::_1);
pointer(4)
}
在pd :: bind的互联网上有很多,所以如果你很好奇,你可以阅读它。
我发现这特别有用,因为它与我的解决方案非常相似。
std::function to member function
感谢所有帮助过的人。
答案 0 :(得分:3)
您将无法将指针指向成员函数分配给普通函数指针:当成员函数将隐式this
指针作为参数时,函数指针不会采用任何其他参数。您可能希望使用std::function<...>
:
std::function<void()> pointer;
B b;
pointer = std::bind(&C::something, &b);
pointer();
D d;
pointer = std::bind(&c::something, &d);
pointer();
如果你传递一个指向对象的指针,并且在和周围有一个合适的成员函数指针,那么你可以避免使用std::function<...>
有一个共同的基类(而上面的代码与缺少的继承一起工作) ,以下代码要求C
是D
}的基础:
void (C::*member)() = &C::something;
C* c = &b;
(c->*member)(); // calls b.something() using B::something()
c = &d;
(c->*member)(); // calls d.something() using D::something()
C ++没有使用&object.member
来表示容易绑定的成员函数的地址。 ......而且,即使它确实如此,它的类型也不会是void(*)()
。
答案 1 :(得分:2)
void(B::*bPointer)();
void(D::*dPointer)();
B b;
D d;
bPointer = &B::something;
(b.*bpointer)();
dPointer = &D::something;
(d.*dPointer)();
您还可以使用std::mem_fn和std::bind。
答案 2 :(得分:1)
这里有很多错误,很难知道从哪里开始。
此:
void(*pointer)();
不声明指向成员函数的指针。它声明了一个指向自由函数的指针(例如,非成员函数)。这两种类型的指针是完全不相关的,你不能在两者之间进行转换。您不能将成员函数的地址分配给指向自由函数的指针,反之亦然。
您需要使用特殊语法声明指向成员的指针。旧的(C ++ 03)语法是:
void (C::*memFn)()
但是,由于指针的类型包含有关该函数所属的类的信息,现在您无法将地址D::something()
分配给memFn
- C
和D
完全无关。
您提到要创建“静态虚拟方法”。没有这样的事情。事实上,“静态”和“虚拟”这两个概念几乎完全相互正交。这个想法毫无意义。这就像是说你要种一个苹果锤。
为什么要尝试将D
对象用作B
对象? D
和B
完全无关。在我看来,你真正应该做的是拥有一个抽象基类A
,以及该ABC的{2}和B
的两个具体实现。然后,指向C
的指针可能指向A
或B
,您可以调用同名的C
方法并获得不同的行为。
最后,在过去的几天里,您发布的问题表明您正在努力学习该语言,方法是敲击一些代码并尝试修复编译器错误的结果。 (我可能会想到其他人,如果是的话,我很抱歉)这不会起作用。你接受了我的建议并获得了good C++ text吗?
答案 3 :(得分:0)
S.th。像
pointer = &D::dosomething;
可能是??
注意:强>
您需要有一个D
的实际实例来调用非静态类成员。
答案 4 :(得分:0)
#include <iostream>
class A
{
private:
int i;
protected:
void (A::*ptr)();
public:
A() : i(0), ptr(&A::methodOne) {}
virtual ~A(){}
void move_ptr()
{
switch(++i)
{
case 0: {ptr = &A::methodOne;} break;
case 1: {ptr = &A::methodTwo;} break;
case 2: {ptr = &A::methodThree;} break;
case 3: {ptr = &A::nonVirtual;} break;
default: {ptr = &A::methodOne; i = 0;} break;
}
}
void call() {(this->*A::ptr)();}
virtual void methodOne() {std::cout<<"A::methodOne\n";}
virtual void methodTwo() {std::cout<<"A::methodTwo\n";}
virtual void methodThree() {std::cout<<"A::methodThree\n";}
void nonVirtual() {std::cout<<"A::nonVirtual\n";}
};
class B : public A
{
public:
B() : A() {}
virtual ~B(){}
virtual void methodOne() {std::cout<<"B::methodOne\n";}
virtual void methodTwo() {std::cout<<"B::methodTwo\n";}
virtual void methodThree() {std::cout<<"B::methodThree\n";}
void nonVirtual() {std::cout<<"B::nonVirtual\n";}
};
int main()
{
A a;
a.call();
a.move_ptr();
a.call();
a.move_ptr();
a.call();
a.move_ptr();
a.call();
B b;
b.call();
b.move_ptr();
b.call();
b.move_ptr();
b.call();
b.move_ptr();
b.call();
}
打印:
A::methodOne
A::methodTwo
A::methodThree
A::nonVirtual
B::methodOne
B::methodTwo
B::methodThree
A::nonVirtual
我会留给你弄清楚为什么最后一行是A::nonVirtual
而不是B::nonVirtual
。一旦你搞清楚了,你就已经知道如何修复它了。