Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;笛卡尔乘积迭代器在第一次迭代时调用基类函数_C++_Templates_Derived Class_Cartesian Product - Fatal编程技术网

C++ C++;笛卡尔乘积迭代器在第一次迭代时调用基类函数

C++ C++;笛卡尔乘积迭代器在第一次迭代时调用基类函数,c++,templates,derived-class,cartesian-product,C++,Templates,Derived Class,Cartesian Product,我正在研究一组n维笛卡尔积类,松散地基于此 对于相同的基本算法集,我有许多不同的数据类型,我想“啊哈!我将使用模板来减少我的总体工作!”而且,到目前为止,它的工作非常出色。我正在使用Boost的迭代器 我的问题是使用一个派生类来处理map。每次迭代都会产生一个映射,但我排除了第二个值为0的对,因为就我的算法而言,它们只是浪费了空间 派生类重载生成迭代器返回值的函数,该函数可以工作。但是,在第一次迭代期间,调用基类的生成器。我很困惑。有人有什么想法吗 以下是相关的代码片段: 每个genRetu

我正在研究一组n维笛卡尔积类,松散地基于此

对于相同的基本算法集,我有许多不同的数据类型,我想“啊哈!我将使用模板来减少我的总体工作!”而且,到目前为止,它的工作非常出色。我正在使用Boost的迭代器

我的问题是使用一个派生类来处理
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);
}