base class 中指向成员函数的指针数组
Array of pointers to member functions in base class
我需要一个指向基类中成员函数的指针数组 class 像这样
class Base {
public:
typedef int(Base::*func)();
func f[3];
Base();
void run();
};
void Base::run()
{
cout << (this->*f[0])() << endl;
cout << (this->*f[1])() << endl;
cout << (this->*f[2])() << endl;
}
函数 运行() 对所有子 classes 都是一样的。但是数组 f[] 中的指针将引用将在子 classes.
中定义的成员函数
class Child: public Base {
public:
typedef int(Child::*func)();
func f[3];
int A();
int B();
int C();
Child();
};
int Child::A()
{
return 1;
}
int Child::B()
{
return 2;
}
int Child::C()
{
return 3;
}
Child::Child()
{
f[0] = &Child::A;
f[1] = &Child::B;
f[2] = &Child::C;
}
如果我运行程序中的这段代码我会遇到问题
Child x;
x.run();
如何操作?
您在这里面临两大障碍。
第一,您永远不会初始化 Base::f
,但这就是 run
的作用。您在子 class 中声明一个成员 f
并在构造函数中对其进行初始化。 Base
classes f
从未被初始化,并且充满了垃圾。当您调用 run
时,它会尝试使用这些随机值。这是未定义的行为。
两个,int(Base::*)()
和int(Child::*)()
是两种截然不同且不兼容的类型。您看起来想要用指向子函数的指针填充数组并从基数 class.
调用它们
有几种方法可以解决此问题:
- 您可以使
run
虚拟化并在子 class 中实现它以调用函数。
- 您可以将函数放在基 class 中并使它们成为虚拟的,这样指向它们的指针将调用派生版本。
- 您可以创建一个
std::function
对象数组而不是指针。
这个有效:
class Base {
public:
typedef int(Base::*func)();
func f[3];
virtual int A() { return 0; }
virtual int B() { return 0; }
virtual int C() { return 0; }
Base() {};
void run()
{
cout << (this->*f[0])() << endl;
cout << (this->*f[1])() << endl;
cout << (this->*f[2])() << endl;
}
};
class Child: public Base {
public:
int A() { return 1; }
int B() { return 2; }
int C() { return 3; }
Child()
{
f[0] = &Base::A;
f[1] = &Base::B;
f[2] = &Base::C;
}
};
我需要一个指向基类中成员函数的指针数组 class 像这样
class Base {
public:
typedef int(Base::*func)();
func f[3];
Base();
void run();
};
void Base::run()
{
cout << (this->*f[0])() << endl;
cout << (this->*f[1])() << endl;
cout << (this->*f[2])() << endl;
}
函数 运行() 对所有子 classes 都是一样的。但是数组 f[] 中的指针将引用将在子 classes.
中定义的成员函数class Child: public Base {
public:
typedef int(Child::*func)();
func f[3];
int A();
int B();
int C();
Child();
};
int Child::A()
{
return 1;
}
int Child::B()
{
return 2;
}
int Child::C()
{
return 3;
}
Child::Child()
{
f[0] = &Child::A;
f[1] = &Child::B;
f[2] = &Child::C;
}
如果我运行程序中的这段代码我会遇到问题
Child x;
x.run();
如何操作?
您在这里面临两大障碍。
第一,您永远不会初始化 Base::f
,但这就是 run
的作用。您在子 class 中声明一个成员 f
并在构造函数中对其进行初始化。 Base
classes f
从未被初始化,并且充满了垃圾。当您调用 run
时,它会尝试使用这些随机值。这是未定义的行为。
两个,int(Base::*)()
和int(Child::*)()
是两种截然不同且不兼容的类型。您看起来想要用指向子函数的指针填充数组并从基数 class.
有几种方法可以解决此问题:
- 您可以使
run
虚拟化并在子 class 中实现它以调用函数。 - 您可以将函数放在基 class 中并使它们成为虚拟的,这样指向它们的指针将调用派生版本。
- 您可以创建一个
std::function
对象数组而不是指针。
这个有效:
class Base {
public:
typedef int(Base::*func)();
func f[3];
virtual int A() { return 0; }
virtual int B() { return 0; }
virtual int C() { return 0; }
Base() {};
void run()
{
cout << (this->*f[0])() << endl;
cout << (this->*f[1])() << endl;
cout << (this->*f[2])() << endl;
}
};
class Child: public Base {
public:
int A() { return 1; }
int B() { return 2; }
int C() { return 3; }
Child()
{
f[0] = &Base::A;
f[1] = &Base::B;
f[2] = &Base::C;
}
};