虚函数调用错误的例子

hittyo 2011-06-03 10:32:39
pure virtual method called
terminate called without an active exception



这个错误很难调试出来,偶尔几天会爆出来一次
我整个服务中就一处使用了纯虚函数,这个虚函数所在的对象是一个socket服务的acceptor,
我一直怀疑是因为一个连接创建后过快调用这个对象,但这个对象的虚表尚未建立。

还请大家帮忙排疑。
...全文
1974 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
Julykey 2011-06-10
  • 打赏
  • 举报
回复
学习了!
上岸の鱼 2011-06-08
  • 打赏
  • 举报
回复
pure virtual method --纯虚函数
调用纯虚函数必然会出错

而纯虚函数被意外调用,很可能是调用了父类的析构函数,而父类的析构函数为纯虚函数的情况
LeoforGame 2011-06-08
  • 打赏
  • 举报
回复
我猜一下,因为asio网络层可能用到多线程,有没有可能在一个线程里面创建这个Handle还没完成,而此时另一个线程调用这个handle去处理马上到来的消息?
LeoforGame 2011-06-08
  • 打赏
  • 举报
回复
楼主是什么项目,用的是boost::asio?
cs0711BF826 2011-06-08
  • 打赏
  • 举报
回复
应该是实现那个纯虚函数的对象被析构了,还在用父类指针调用这个函数。

建议在析构函数里面加入打印语句,查一下有没有被析构
  • 打赏
  • 举报
回复
我找到了几个链接,应该能解决楼主遇到的问题
http://edu.codepub.com/2009/0617/6496.php
http://topic.csdn.net/t/20041216/18/3652183.html
http://www.iteye.com/topic/167098
请不要被pathuang68混淆视听
  • 打赏
  • 举报
回复
pathuang68你给出的代码和楼主的一样你搞不清楚吗?
public:
Sth(boost::asio::io_service& io_service):
Handler(io_service)//这边调用父类构造函数
{}

A(int a):B(a)
{
}

有什么区别?你在B的构造函数里添加输出语句看看构造A的时候有没有调用B
pamtry 2011-06-07
  • 打赏
  • 举报
回复
mark一下

这个问题以后再来看
smwhotjay 2011-06-07
  • 打赏
  • 举报
回复
pure virtual method called
纯虚函数call.
你肯定调用的是dll或lib. 而接口或lib未更新为最新版的..我遇到过..你重新把工程bulid. dll也是.再把dll,头文件,lib都确保是最新的.
FrankHB1989 2011-06-05
  • 打赏
  • 举报
回复
构造函数调用成员函数要小心。
nickylong1988 2011-06-05
  • 打赏
  • 举报
回复
这么难啊
luciferisnotsatan 2011-06-03
  • 打赏
  • 举报
回复
   class A;

void fcn( A* );

class A
{
public:
virtual void f() = 0;
A() { fcn( this ); }
};

class B : A
{
void f() { }
};

void fcn( A* p )
{
p->f();
}

// The declaration below invokes class B's constructor, which
// first calls class A's constructor, which calls fcn. Then
// fcn calls A::f, which is a pure virtual function, and
// this causes the run-time error. B has not been constructed
// at this point, so the B::f cannot be called. You would not
// want it to be called because it could depend on something
// in B that has not been initialized yet.

B b;

还真有这种代码,能调到纯虚函数,长见识了。
www_adintr_com 2011-06-03
  • 打赏
  • 举报
回复

是这种错误吗?
pathuang68 2011-06-03
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hittyo 的回复:]

引用 15 楼 pathuang68 的回复:

C/C++ code

class Sth : public Handler
{
public:
Sth(boost::asio::io_service& io_service):
Handler(io_service)//这边调用父类构造函数
{}
// 1. 上面那样显示调用抽象类的Handler的构造函数……
[/Quote]

就两条:
1. 抽象类是不能实例化的,即不能像11楼Sth中那样显式调用构造函数
2. 抽象类的构造函数,是给子类通过初始化列表的方式对基类中的某些成员变量初始化的

比较标准的做法就是我在20楼给出的代码。
turing-complete 2011-06-03
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 hittyo 的回复:]
是不能构造基类,但是实例化子类
new Sth(io_service);
是会调用父类的构造函数 Handler(io_service) 实现一些功能,
我觉得可能是这样实现会有问题。
[/Quote]
抽象类可以有构造函数,而且在有数据成员的情况下,应当有构造函数供派生类调用,最好是protected。
有构造函数,不意味着一定要实例化。
pathuang68 2011-06-03
  • 打赏
  • 举报
回复
稍微解释一下:

class A : public B
{
public:
A(int a):B(a) // 这个地方就是所谓的初始化列表,在这里你看到调用了抽象类的构造函数
{ // A类继承了B中的数据成员a,但通过B的构造函数去初始化
}

void fun()
{
cout << a << endl;
}
};
pathuang68 2011-06-03
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 hittyo 的回复:]

引用 17 楼 pathuang68 的回复:

如果有什么数据要传递给基类的话,在楼主所设的应用场景下,可以使用初始化列表的方式来处理。同时把在子类中显示调用基类构造函数的代码删除。


是想在基类中初始化一个成员变量,而这个成员变量又不能在子类中初始化。
[/Quote]
那就用初始化列表的方式来解决这个问题,参考下面的代码:

#include <iostream>
using namespace std;
class B
{
protected:
int a;
public:
B(int a)
{
this->a = a;
}

virtual void fun() = 0;

virtual ~B()
{
}
};

class A : public B
{
public:
A(int a):B(a)
{
}

void fun()
{
cout << a << endl;
}
};

int main(void)
{
B* b = new A(10);
b->fun();

return 0;
}


以上代码经过验证,可以实现你的意图,而且没有问题。
hittyo 2011-06-03
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 pathuang68 的回复:]

如果有什么数据要传递给基类的话,在楼主所设的应用场景下,可以使用初始化列表的方式来处理。同时把在子类中显示调用基类构造函数的代码删除。
[/Quote]

是想在基类中初始化一个成员变量,而这个成员变量又不能在子类中初始化。
hittyo 2011-06-03
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 pathuang68 的回复:]

C/C++ code

class Sth : public Handler
{
public:
Sth(boost::asio::io_service& io_service):
Handler(io_service)//这边调用父类构造函数
{}
// 1. 上面那样显示调用抽象类的Handler的构造函数,难道有什么特别的意……
[/Quote]

嗯,多谢指导,现实中我实现并顺利通过编译,并貌似正常运行。
不能这么做的理由能不能再详细一说,在下洗耳躬听。
pathuang68 2011-06-03
  • 打赏
  • 举报
回复
如果有什么数据要传递给基类的话,在楼主所设的应用场景下,可以使用初始化列表的方式来处理。同时把在子类中显示调用基类构造函数的代码删除。
加载更多回复(20)

64,646

社区成员

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

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