0

Searched around and couldn't find any advice to my problem. I'm trying to make a copy constructor for a class that has a private variable that includes a pointer to an Abstract Base Class.

#include "BaseClass.hh"

ClassA::ClassA()
{ }
/* Copy construct a ClassA object */
ClassA::ClassA(const ClassA& obj)
{
    std::map<std::string, BaseClass*>::const_iterator it;
    //ClassA copy = obj;

    for(it = obj.ind.begin(); it != obj.ind.end(); it++)
    {
        copy.ind[it->first]=(it->second);
    }
}

//in .hh file
private:
std::map<std::string, BaseClass*> ind;

Am I even close? If not, how could I fix this?

  • 1
    Did you mean to ++it as well as the it++ in the 'for' clause? – Scott Earle Oct 08 '12 at 02:16
  • How are BaseClass & ClassA related ? Does ClassA publicly inherit BaseClass ? – Jagannath Oct 08 '12 at 02:18
  • I think the first thing you have to explain is: why do you need a custom copy constructor? What does the one provided for you do that you wish it didn't? Also has others have noted : does ClassA inherit from BaseClass? Or is it a different relationship? – Rollie Oct 08 '12 at 02:23
  • it does not inherit BaseClass, it is just included as a header. Edited code to include it. – user1727556 Oct 08 '12 at 02:37

1 Answers1

1

There are couple of issues here.

  1. ++it; repeated in the for loop.
  2. ClassA copy = obj; Once you return from the copy constructor, the variable copy is destroyed. So, you are not doing any copy here.
  3. If you wish to put the value in the map as a pointer, then you need to allocate memory for the pointer variable.
  4. Since you have are having the value in the map as BaseClass pointer, you need to know the exact type you wish to allocate memory for. The key could help here.

I'm taking the liberty of C++11 tag here.This is just for illustration purpose. Take the idea and implement it as it fits your needs. If you observe, I did not release the memory here.Left it for you.

class BaseA
{
public:
    virtual void Print() = 0;
};

class Derived1A : public BaseA
{
    virtual void Print() 
    {
        std::cout << "Derived1A\n";
    }
};

class Derived2A : public BaseA
{
    virtual void Print() 
    {
        std::cout << "Derived2A\n";
    }
};


std::map<std::string, std::function<BaseA*()>> factory;


class ClassA
{

public:
    ClassA()
    {
        for (auto it = factory.begin(); it != factory.end(); ++it)
        {
            typedef std::pair<const std::string, BaseA*> Pair;
            mapType_m.insert(Pair(it->first, it->second()));
        }
    }

    ClassA(const ClassA& other)
    {
        for (auto it = other.mapType_m.begin(); it != other.mapType_m.end(); ++it)
        {           
            typedef std::pair<const std::string, BaseA*> Pair;
            mapType_m.insert(Pair(it->first, factory[it->first]()));
        }
    }

    void Print()
    {
        for (auto it = mapType_m.begin(); it != mapType_m.end(); ++it)
        {
            std::cout << "key:" << it->first << "\tValue:";
            it->second->Print() ;
            std::cout << "\n";
        }
    }

private:
    std::map<std::string, BaseA*> mapType_m;

};


int main()
{
    factory["Derived1A"] = []() { return new Derived1A(); };
    factory["Derived2A"] = []() { return new Derived2A(); };


    ClassA c1;
    ClassA c2 = c1;
    c2.Print();
}
Jagannath
  • 3,995
  • 26
  • 30
  • 1. Thanks for noticing, that was from a previous while loop. removed it. – user1727556 Oct 08 '12 at 02:39
  • 2. Ok, understand this part. 3. and 4. I also understand that I need to allocate memory, but I couldn't figure out how to do it since it's an abstract base class, meaning that BaseClass* copy = New BaseClass; doesn't work? I also have no idea what you mean that the key could help here :( – user1727556 Oct 08 '12 at 02:42
  • Wow! Thank you for taking the time to explain this to me in such detail. Now I see what you meant. This really helped me. Thanks again! – user1727556 Oct 08 '12 at 04:20