C ++在基类和派生类上进行迭代

时间:2019-05-18 02:13:31

标签: c++ iterator

我正在尝试找到一种方法来使迭代器在自定义对象列表和从该自定义对象派生的对象列表上工作。我的目标(也许是被误导了)是允许我保留“生产”代码和对象的完整性,但可以从我正在尝试的“实验/扩展”事物中访问它们。

这是我要做的事的一个很小的例子。

#include <iostream>
#include <list>
using std::cout;
using std::endl;
using std::cin;
using std::list;

struct comp{
    double x,y;

    void print(){
        cout << "x: " << x << endl;
        cout << "y: " << y << endl;
    }
    comp(){
        x = 0;
        y = 0;
    }
    comp(double X, double Y){
        x = X;
        y = Y;
    }
    // Standard/Tested Member Functions
};

struct base{
    list<comp> components;
    double known, tested, variables;

    void print_comps(){
        for (list<comp>::iterator it = components.begin(); it != components.end(); ++it){
            // Ideally, this function should work for comp1 and comp1x
            // as inherited in the basex class
            it->print();
        }
    }
    // Standard/Tested Member Functions
};

struct compx : comp{
    double w,z;
    double some, alter, nates;

    void print(){
        cout << "x: " << x << endl;
        cout << "y: " << y << endl;
        cout << "w: " << w << endl;
        cout << "z: " << z << endl;
    }
    compx(){
        x = 0;
        y = 0;
        z = 0;
        w = 0;
    }
    compx(double X, double Y, double Z, double W){
        x = X;
        y = Y;
        z = Z;
        w = W;
    }
    // Experimental/Un-tested Member Functions
};

struct basex : base{
    list<compx> components;
    double exper, imen, tal;

    // void print_comps(){} // This should be inherited from base

    // Experimental/Un-tested Member Functions
};

int main(){

    base compilation1;
    compilation1.components.push_back(comp(1,2));
    compilation1.components.push_back(comp(3,4));
    cout << "printing normal struct" << endl;
    compilation1.print_comps();

    cout << endl;

    basex compilation2;
    compilation2.components.push_back(compx(9, 5, 5, 6));
    compilation2.components.push_back(compx(7, 2, 1, 8));
    cout << "printing extended struct" << endl;
    compilation2.print_comps();     // Prints nothing

    cout << endl;

    cout << "Printing via specific iterator" << endl;
    for (list<compx>::iterator it = compilation2.components.begin(); it != compilation2.components.end(); ++it){
        it->print();    // Works as expected.
    }

    cout << endl << endl << "Press ENTER to exit." << endl; cin.get();
    return 0;
}

理想情况下,我将能够在相同的函数中迭代原始类和扩展类,因此我不会用所有原始代码弄乱扩展类。这样一来,只要这些变量或函数经过验证或成熟,我就可以将代码从扩展类移至原始类。

背景:

  • 我还没有结婚列表-任何其他可迭代的类都可以。
  • 我不是开发人员-我是ChemE,试图在不破坏我已经构建的内容的情况下使日常任务变得更加轻松。
  • git存储库中的分支不是一个很好的解决方案,因为其他非开发人员(可能受到代码挑战)可能会尝试扩展它。让他们甚至使用一个分支都是一个奇迹。
  • 我在Linux(Lubuntu)上使用g ++ 7.4.0,在Windows 7上使用6.3.0。

TL; DR:

是否有一种方法可以使list<parent_object>的迭代器也可以迭代list<child_object>

2 个答案:

答案 0 :(得分:1)

可以通过将base作为模板http://cpp.sh/7r2x6a

来解决
template<typename T>
struct base
{
    list<T> components;
    double known, tested, variables;

    void print_comps(){
        for (auto it = components.begin(); it != components.end(); ++it){
            // Ideally, this function should work for comp1 and comp1x
            // as inherited in the basex class
            it->print();
        }
    }
    // Standard/Tested Member Functions
};

答案 1 :(得分:1)

如果可以将compcompx对象在同一个list中混合在一起是可以的,那么可以使用模板化函数来避免重复的代码。

例如,您可以在struct base中执行以下操作:

struct base{
   list<comp> components;
   double known, tested, variables;

   void print_comps() {print_comps_aux<comp>(components);}

   protected:
      template <typename CompType> void print_comps_aux(list<CompType> & compsArg)
      {
         for (typename list<CompType>::iterator it = compsArg.begin(); it != compsArg.end(); ++it){
            it->print();
         }
      }

   // Standard/Tested Member Functions
};

...,然后在您的struct basex中,您可以拥有以下内容:

[...]

void print_comps() {print_comps_aux<compx>(components);}