3

Please consider the following code :

    #include <iostream>
    using namespace std;
    class superclass;
    class subclass;
    class subclass2;
    class superclass
    {
    public:
        unsigned int a;
        superclass **superman;

    };
    class subclass : public superclass
    {
    public:
        unsigned int b;
    };
    class subclass2 : public superclass
    {
    public:
        unsigned int b;
    };
    class runner
    {
    public:
        superclass **superman;
        runner()
        {
            *superman=new superclass[2];
            superman[0]=new subclass;
            superman[0]->a=3;
            superman[1]=new subclass2;
            superman[1]->a=4;
        }

    };
    int main() {

        runner r;
        cout<<r.superman[0]->a<<" "<<r.superman[1]->a;
        return 0;
    }

As you can see I want to create a dynamicaly alocated storage of references to a parent class each of which can then point to a child class how ever I do not know how to extract the child class out again from that array so i may access its variable b;

I have tried the following approaches but they have not worked for me and give the error "conversion from 'superclass*' to non-scalar type 'subclass' requested" and "conversion from 'superclass*' to non-scalar type 'subclass2' requested"

    subclass s1=r.superman[0];
    subclass2 s2=r.superman[1];

I am sure I am missing something small.

PS: I could not find a similar question, but if it exists, please redirect me, also i would like a solution that does not require me to use vector or any inbuilt pre-existing library class.

3
  • 1
    You have too many stars in your code. I recommend boost::ptr_vector<superclass>, or std::vector<std::unique_ptr<superclass>>. Commented Jan 15, 2013 at 9:05
  • I compiled it in my GCC and there is no error. The output is 3 4. Which compiler do you have? Commented Jan 15, 2013 at 9:12
  • @Masoud The first part is fine and output is as you have said, it's this part that's causing the problem.subclass s1=r.superman[0]; subclass2 s2=r.superman[1]; Commented Jan 15, 2013 at 9:24

3 Answers 3

3

You really want smart pointer in this case and superclass doesn't need to have a pointer to itself. You can can store superclass pointer in vector which points to real derived class so the polymorphism still works:

#include <memory>
#include <vector>

struct superclass
{
public:
  superclass() : a(0) {}
  virtual ~superclass() {}  // it's important to define virtual destructor as superclass is a base class
  int getA() const { return a; }

private:
  unsigned int a;
};

class subclass : public superclass
{
public:
    unsigned int b;
};
class subclass2 : public superclass
{
public:
    unsigned int b;
};

class runner
{
public:
  std::vector<std::unique_ptr<superclass>> superman;
  runner()
  {    
      superman.emplace_back(new subclass());
      superman.emplace_back(new subclass2());
  }    
};

Then you can access it simply:

   int main() 
   {    
       runner r;
       std::cout << r.superman[0]->getA() <<" " < <r.superman[1]->getA();
       return 0;
   }

Side note: hide your data if you can, access data through set/get functions, don't declare members as public.

Sign up to request clarification or add additional context in comments.

Comments

1
    superclass **superman;
    runner()
    {
        *superman=...

These few lines of code give undefined behaviour to the code. You cannot dereference an uninitialised pointer and expect everything to work just fine.

Comments

1

Add a virtual destructor in superclass and use dynamic_cast:

class superclass
{
public:
    unsigned int a;
    superclass **superman;
    virtual ~superclass(){}; // You must at least have one virtual method
                             // in your superclass and destructor is good choice 
                             // Otherwise, dynamic_cast wouldn't work:
                             // error: ... (source type is not polymorphic) !
};
// ...
// s1 and s2 must be pointers:
subclass  *s1=dynamic_cast<subclass* >(r.superman[0]);
subclass2 *s2=dynamic_cast<subclass2*>(r.superman[1]);
//...

Note: Be careful about casting from base class to a derived class. And don't forget to release allocated memory.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.