1
votes

I have a Base class with Derived1 and Derived2 derived classes and a Consumer class.

I want to create a vector of Base pointers with the two derived class objects to then pass to the consumer class so it can get derived class details using

pointervec.at(0).i

I've been stuck on this for ages and cannot get it to work. This is a simplified version of what I have. I'm concerned about the syntax around creating the vector, passing it to the thread and accessing different indexes.

#include<vector>
#include<thread>
#include<iostream>

using namespace std;

class Base
{
public:
    Base() {};
    void dosomething() {cout<<i<<endl;}
    int i;
};

class Derived1 : public Base
{
public:
    Derived1() {i = 5;}
};

class Derived2 : public Base
{
public:
    Derived2() {i = 10;}
};

class Consumer
{
public:
    Consumer();
    void dostuff( vector<Base> &pointervec) {cout<<5<<endl;}
};

int main( int argc, char ** argv )
{
    Derived1 derived1;
    Derived2 derived2;

    vector<Base*>pointervec;
    pointervec.push_back(&derived1);
    pointervec.push_back(&derived2);

    std::thread t1(&Derived1::dosomething, &derived1);
    std::thread t2(&Derived2::dosomething, &derived2);
    std::thread t3(&Consumer::dostuff, ref(pointervec));

    t1.join();
    t2.join();
    t3.join();
}
1
vector<Base> is not vector<Base*>MikeCAT
Your example is probably too simplified from the real code you have. Why do you actually need a vector<Base>& type for dostuff(), instead of that vector<Base*> that you're passing around?πάντα ῥεῖ
my consumer class needs to accept a range of derived classes, so to make it work with any derived class, I use Base pointers. I have used an array of pointers before Ranger * ptrarray[3]; ptrarray[0]=&derived1; ptrarray[1]=&derived2; ptrarray[2]=&derived3; and accessed in my consumer using ptrarray[i]->variable. but now I want to make it flexible to work with any number of classes.acv17
@acv17 to elaborate on Mike's comment, pay attention to the type of pointervec argument of Consumer::dostuff and compare with the type that you pass to the thread.eerorika
@acv17 I still don't get why doStuff() needs a vector<Base>, and what cannot be satisfied in there using vector<Base*> there.πάντα ῥεῖ

1 Answers

4
votes

To make your example work, there are a few mistakes that need to be corrected.

  1. As Consumer::doStuff is a non-static member function, you need an instance of Consumer to run it on.
  2. Because of above, Consumer needs a defined constructor
  3. The signature of doStuff needs to take a (reference to a) vector of Base pointers, not Base objects
  4. Thread t3 needs said instance of Consumer as its first forwarded parameter (to provide the this parameter.

Final working code:

#include<vector>
#include<thread>
#include<iostream>

using namespace std;

class Base
{
public:
    Base() {};
    void dosomething() {cout<<i<<endl;}
    int i;
};

class Derived1 : public Base
{
public:
    Derived1() {i = 5;}
};

class Derived2 : public Base
{
public:
    Derived2() {i = 10;}
};

class Consumer
{
public:
    Consumer() {}
    void dostuff( vector<Base*> &pointervec) {cout<<pointervec.at(0)->i<<endl;}
};

int main( int argc, char ** argv )
{
    Derived1 derived1;
    Derived2 derived2;

    Consumer c;
    vector<Base*>pointervec;
    pointervec.push_back(&derived1);
    pointervec.push_back(&derived2);

    std::thread t1(&Derived1::dosomething, &derived1);
    std::thread t2(&Derived2::dosomething, &derived2);
    std::thread t3(&Consumer::dostuff, &c, ref(pointervec));

    t1.join();
    t2.join();
    t3.join();
}