函数指针问题

sunnystone614 2009-03-06 03:20:42

#include <iostream>
using namespace std;

class Mammal
{
public:
Mammal():itsAge(1) { cout << "Mammal constructor...\n"; }
virtual ~Mammal() { cout << "Mammal destructor...\n"; }
virtual void Speak() const = 0;
virtual void Move() const = 0;
protected:
int itsAge;
};

class Dog:public Mammal
{
public:
void Speak() const { cout << "Woof!" << endl; }
void Move() const { cout << "Walking to heel..." << endl; }
};


class Cat:public Mammal
{
public:
void Speak() const { cout << "Meow!" << endl; }
void Move() const { cout << "slinking..." << endl; }
};


class Horse:public Mammal
{
public:
void Speak() const { cout << "Winnie!" << endl; }
void Move() const { cout << "Galloping..." << endl; }
};


int main()
{
void (Mammal::*pFunc) () const = 0;
Mammal * ptr = 0;
int Animal;
int Method;
bool fQuit = false;

while (fQuit == false)
{
cout << "(0)Quit (1)dog (2)cat (3)horse: ";
cin >> Animal;
switch (Animal)
{
case 1: ptr = new Dog; break;
case 2: ptr = new Cat; break;
case 3: ptr = new Horse; break;
default: fQuit = true; break;
}
if (fQuit == false)
{
cout << "(1)Speak (2)Move: ";
cin >> Method;
switch (Method)
{
case 1: pFunc = Mammal::Speak; break;
// 在编译的时候这个地方报错:“Mammal::Speak”: 函数调用缺少参数列表请 表;使用“&Mammal::Speak”创建指向成员的指针
default: pFunc = Mammal::Move; break;
}

(ptr->*pFunc)();
delete ptr;
}
}
return 0;
}


小弟是个新手,这段代码是照书上敲的。但是编译不能通过。看来成员函数的指针不能直接赋给普通函数指针。
如编译器提示在“Mammal::Speak”前面加上“&”就可以编译通过,也能正常运行,为什么要在“Mammal::Speak”前面加一个“&”呢?函数名不就是一个指针么?很迷惑,不知道为什么。
还有书上为什么没有加“&”呢?
...全文
164 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojiang6481 2010-09-29
  • 打赏
  • 举报
回复
我这句也报错:
(ptr -> * pFunc)();
// error C2059: 语法错误 : “*”

请问是怎么回事啊?
dongpy 2009-03-06
  • 打赏
  • 举报
回复
要不要加&由编译器决定的,有些编译器加不加都能通过。
sunnystone614 2009-03-06
  • 打赏
  • 举报
回复
那看来就是编译器的问题啦?9楼的,你在vc6下面跑了没问题?
lizhizhe2000 2009-03-06
  • 打赏
  • 举报
回复
我觉得tangshuiling 的解释是合理的
imdemon 2009-03-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sunnystone614 的回复:]
可是函数的名字不就是一个函数的指针么?为什么还要用取地址符号呢?
[/Quote]

你用的肯定不是VC6。。。

我的理解是:函数名不是函数指针,但可以退化成函数指针。


sagegz 2009-03-06
  • 打赏
  • 举报
回复
你的编译器不支持把函数名称当成函数地址,所以需要显示的使用&来告诉编译器函数的地址.
tangshuiling 2009-03-06
  • 打赏
  • 举报
回复

楼主所说的问题牵扯到静态编译、动态编译的概念。
普通的函数在预编译时期就确定了函数的重定位地址,而成员函数属于运行时期的地址定位。
Mammal::Speak如此写法,在预编译期间编译器无法确定你的Speak是类成员还是类函数,加上&符号是确切的告诉
编译器,我的&Mammal::Speak给的是个函数的地址而不是一个成员变量,并且给的是个运行时态的地址,编译器
有时也会做出很多匪夷所思的事情,有时必须你明确的告诉它该干什么,不该干什么

lingyin55 2009-03-06
  • 打赏
  • 举报
回复
up
[Quote=引用 1 楼 akirya 的回复:]
标准写法是需要增加&符号的
有些编译器不写&也能编译过去.
书上用的编译器正好是不用&能编译过去的.
你用的是不支持不写&的

所以嘛,以编译器为准,写上&
[/Quote]
sunnystone614 2009-03-06
  • 打赏
  • 举报
回复
哦,就是想知道这是为什么。
是不是在 成员函数指针 赋值给 普通函数指针 的时候有什么其他要求,而加上这个&正好满足了这个要求。
我把 普通函数指针 赋值给 普通函数指针的时候不会出现这个问题。
  • 打赏
  • 举报
回复
一般来说可以认为函数名就是函数指针,加个&也还是函数指针,不会变.
估计是编译器的问题吧,你加了可以通过就行了.
chenzhp 2009-03-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sunnystone614 的回复:]
可是函数的名字不就是一个函数的指针么?为什么还要用取地址符号呢?
[/Quote]

[Quote=引用 1 楼 akirya 的回复:]
标准写法是需要增加&符号的
有些编译器不写&也能编译过去.
书上用的编译器正好是不用&能编译过去的.
你用的是不支持不写&的

所以嘛,以编译器为准,写上&
[/Quote]
sunnystone614 2009-03-06
  • 打赏
  • 举报
回复
可是函数的名字不就是一个函数的指针么?为什么还要用取地址符号呢?
  • 打赏
  • 举报
回复
标准写法是需要增加&符号的
有些编译器不写&也能编译过去.
书上用的编译器正好是不用&能编译过去的.
你用的是不支持不写&的

所以嘛,以编译器为准,写上&

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧