Copy constructor for class that has member without

2019-07-24 19:57发布

问题:

I have a class:

class Geometry{
    std::vector<Subset *> subsets;
    int verticesCount;
    ...
};

I want to add a copy constructor, so I can make a deep copy of that object (with own subsets, NOT only own pointers to same subsets).

I have tried this:

 Geometry & Geometry::operator=(const Geometry &other){
      verticesCount = other.verticesCount;
      Subset * subset = 0;
      for(unsigned int i=0; i<other.subsets.size(); i++){
           subset = new Subset();
           subsets.push_back(subset);
      }
      ...
      return *this;
 }

The problem is Subset has none default constructor, so I get error at subset = new Subset().

I also have more members that don't have default constructors.

How to solve that problem?

I would prefer NOT to add default constructors for all that members (Subset etc.) The best solution would be NOT to change member classes at all (Subset etc.), but I can add something to them, if it's necessary.

They don't have default constructors for reasons, e.g. security (I don't want to let somebody create a Model3D class without giving filename (so the vertex buffers can be created and I can assume that all Model3D objects has not-empty filename associated).


edit:

Because of comment. Subset is an example of member class without default constructor.

In that case it's my own class:

class Subset{
    ...
    public:
        Subset(bool useLineTopology, int vertexIndexStart, int vertexIndexAmmount = -1);
        ...
};

But I also have many others members without default constructor, like DirectX's ID3D11Buffer * constantBuffer.

回答1:

If your Subset() class has a copy constructor then you can do as follows:

std::vector<Subset *>::const_iterator it ; // use iterators
for ( it = other.subsets.begin() ; it != other.subsets.end() ; ++it )
    subset.push_back( new Subset( *it )) ; // add a copy of original subset.

If your Subset() does not have copy constructor then you CANNOT copy.

Also, you need to remember to have ~GeometryStructure() in order to delete all Subset() objects from the subset std::vector



回答2:

You're making a deep copy, so your loop should look like

  for(unsigned int i=0; i<other.subsets.size(); i++){
       subsets.push_back(new Subset(other.subsets[i]));
  }

that is, you need a copy constructor for the elements. Even if Subset had a default constructor, you wouldn't be copying anything with it.



回答3:

What about:

class Geometry{
    std::vector<Subset> subsets;
    int verticesCount;
    ...
};

if you implement copy and/or move semantics to your Subset class, you do not need to create constructors because the compiler will take charge of invoking Subset copy constructors et al. Other favorable point is that you do not need to worry about destructing subsets when your Geometry instances are being destructed.