首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >虚函数问题

虚函数问题
EN

Stack Overflow用户
提问于 2010-01-15 20:18:51
回答 4查看 373关注 0票数 0
代码语言:javascript
复制
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>

class Helper 
{
public:
    Helper() { init(); }
    virtual void print() {
        int nSize = m_vItems.size();
        std::cout << "Size : " << nSize << std::endl;
        std::cout << "Items: " << std::endl;
        for(int i=0; i<nSize; i++) {
            std::cout << m_vItems[i] << std::endl;
        }
    }
protected:
    virtual void init() { m_vItems.push_back("A"); }
    std::vector<std::string> m_vItems;
};

class ItemsHelper : public Helper
{
public:
    ItemsHelper() { }
protected:
    virtual void init() { 
        Helper::init();
        m_vItems.push_back("B");
    }
};

int _tmain(int argc, _TCHAR* argv[]) {
    ItemsHelper h;
    h.print();
}

这个输出是向量的大小为1,我预期大小为2,因为在ItemsHelper::init函数中,我调用了基类Helper::init()函数,然后我向向量添加了第二个项。问题是,ItemsHelper::init没有被调用,而是调用了基类init函数。

我希望调用ItemsHelper::init函数,我可以通过在ItemsHelper ctor中而不是在基类中调用init函数来实现这一点。但是,问题是,是否有更好的方法来实现这一点,并且仍然在基类中保留对init()的调用?因为如果我想创建一个Helper对象而不是一个ItemsHelper,那么init函数就永远不会被调用。

顺便说一句,这是我在一个大得多的对象中看到的一个问题的简化版本,例如,我只是编造了这些对象。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-01-15 20:21:46

在基类构造函数中,派生类尚未构造,因此派生类上的overriden函数不可用。这里有个常见问题条目..。我找不到。

最简单的解决方案是将initinit部分放到Helper构造函数中,将.push_back("B")放到ItemsHelper构造函数中。这似乎做了您想要做的事情,并且删除了不必要的init虚拟函数。

票数 7
EN

Stack Overflow用户

发布于 2010-01-15 20:24:47

请注意,在构造函数中,虚拟函数并不像“预期的”那样工作!

代码语言:javascript
复制
Helper() { init(); }

在这里,init()将始终调用当前类(Helper)的"init“,即使它被标记为虚拟。

编辑:上面有一个相似问题

票数 4
EN

Stack Overflow用户

发布于 2010-01-15 20:30:06

通常(除非您完全了解如何指定构造函数和虚拟函数来工作),否则不应该在构造函数中调用虚拟函数,因为通常不会得到该函数的“最虚拟”版本。在构造函数中虚拟函数如何工作的快速版本是,当调用虚拟函数时,您将得到当前正在构建的类的“当前”级别的函数。

详情请参阅下列文章:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2074494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档