#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函数就永远不会被调用。
顺便说一句,这是我在一个大得多的对象中看到的一个问题的简化版本,例如,我只是编造了这些对象。
发布于 2010-01-15 20:21:46
在基类构造函数中,派生类尚未构造,因此派生类上的overriden函数不可用。这里有个常见问题条目..。我找不到。
最简单的解决方案是将init的init部分放到Helper构造函数中,将.push_back("B")放到ItemsHelper构造函数中。这似乎做了您想要做的事情,并且删除了不必要的init虚拟函数。
发布于 2010-01-15 20:24:47
请注意,在构造函数中,虚拟函数并不像“预期的”那样工作!
Helper() { init(); }在这里,init()将始终调用当前类(Helper)的"init“,即使它被标记为虚拟。
编辑:上面有一个相似问题。
发布于 2010-01-15 20:30:06
通常(除非您完全了解如何指定构造函数和虚拟函数来工作),否则不应该在构造函数中调用虚拟函数,因为通常不会得到该函数的“最虚拟”版本。在构造函数中虚拟函数如何工作的快速版本是,当调用虚拟函数时,您将得到当前正在构建的类的“当前”级别的函数。
详情请参阅下列文章:
https://stackoverflow.com/questions/2074494
复制相似问题