C++ C++;笛卡尔乘积迭代器在第一次迭代时调用基类函数
我正在研究一组n维笛卡尔积类,松散地基于此 对于相同的基本算法集,我有许多不同的数据类型,我想“啊哈!我将使用模板来减少我的总体工作!”而且,到目前为止,它的工作非常出色。我正在使用Boost的迭代器 我的问题是使用一个派生类来处理C++ C++;笛卡尔乘积迭代器在第一次迭代时调用基类函数,c++,templates,derived-class,cartesian-product,C++,Templates,Derived Class,Cartesian Product,我正在研究一组n维笛卡尔积类,松散地基于此 对于相同的基本算法集,我有许多不同的数据类型,我想“啊哈!我将使用模板来减少我的总体工作!”而且,到目前为止,它的工作非常出色。我正在使用Boost的迭代器 我的问题是使用一个派生类来处理map。每次迭代都会产生一个映射,但我排除了第二个值为0的对,因为就我的算法而言,它们只是浪费了空间 派生类重载生成迭代器返回值的函数,该函数可以工作。但是,在第一次迭代期间,调用基类的生成器。我很困惑。有人有什么想法吗 以下是相关的代码片段: 每个genRetu
map
。每次迭代都会产生一个映射
,但我排除了第二个值为0的对,因为就我的算法而言,它们只是浪费了空间
派生类重载生成迭代器返回值的函数,该函数可以工作。但是,在第一次迭代期间,调用基类的生成器。我很困惑。有人有什么想法吗
以下是相关的代码片段:
每个genReturnValue在每次调用中打印其类(基类或派生类)。基类按其应有的方式运行。但是,派生类没有。第一次迭代调用基类genReturnValue,0不会被过滤掉。然而,进一步的迭代会这样做 由于这是我第一次涉足模板和派生类,我确信我遗漏了一些明显的东西,但就我的一生而言,我无法找到它。GCC 4.6.3和Clang 3.0-6提供相同的输出 停
<>编辑:我在C++编程方面比较新。我愿意接受批评,不管是风格还是其他方面,如果你有任何意见的话。谢谢 实际上,它与指针无关;相反,它是
虚拟
功能的限制
在构造和销毁期间,由于基类相对于派生类的构造和销毁顺序,虚拟调用不能是纯虚拟的,因此它们是静态解析的
也就是说,在Base
的构造函数或析构函数中对virtualfunc
的调用(以某种方式)解析为Base::virtualfunc
。如果这是一个纯虚函数,则会出现未定义的行为
因此,一般准则是:
- 从不从构造函数或析构函数调用虚函数
struct Base {
Base() { call(); }
virtual call() { std::cout << "Base\n"; }
};
struct Derived: Base {
Derived(int i): _i(i);
virtual call() { std::cout << "Derived" << _i << "\n"; }
int _i;
};
int main() {
Derived d(1);
};
struct Base{
Base(){call();}
虚拟调用(){std::cout您是基类CartProductIterator2DMap
有一个调用虚拟函数的构造函数:
CartProductIterator2DMap(const Container2DMap &container) {
rangeIterSetup(container);
}
此虚拟函数最终调用另一个虚拟函数:genReturnValue
现在,当基类构造函数正在执行时,派生类尚未构造。因此,基类构造函数对genReturnValue
的调用调用了CartProductIterator2DMap::genReturnValue
。但随后的调用(在对象完全构造之后)调用:DerivedCPIterator::genReturnValue
您需要确保您的基类构造函数不会调用任何虚拟函数。哇,太好了。非常感谢您。现在我知道了基本策略,这些理由非常有道理。感谢您花时间回答。
struct Base {
Base() { call(); }
virtual call() { std::cout << "Base\n"; }
};
struct Derived: Base {
Derived(int i): _i(i);
virtual call() { std::cout << "Derived" << _i << "\n"; }
int _i;
};
int main() {
Derived d(1);
};
CartProductIterator2DMap(const Container2DMap &container) {
rangeIterSetup(container);
}