【问题标题】:Copy constructor for class that has member without default constructor in C++在 C++ 中具有没有默认构造函数的成员的类的复制构造函数
【发布时间】:2014-04-15 19:49:30
【问题描述】:

我有一堂课:

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

我想添加一个复制构造函数,所以我可以制作该对象的深拷贝(使用自己的subsetsNOT只有自己的指针 到相同的subsets)。

我试过这个:

 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;
 }

问题是Subsetnone 默认构造函数,所以我在subset = new Subset() 得到错误。

我还有更多没有默认构造函数的成员。

如何解决这个问题?

我希望不为所有成员添加默认构造函数Subset 等)最好的解决方案是完全更改成员类(@ 987654328@ 等),但如果有必要,我可以添加一些内容。

出于原因,它们没有默认构造函数,例如安全性(我不想让某人在不提供文件名的情况下创建Model3D 类(因此可以创建顶点缓冲区,我可以假设所有Model3D 对象都关联了非空文件名)。


编辑:

因为评论。 Subset 是一个没有默认构造函数的成员类的例子。

在这种情况下,这是我自己的课程:

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

但我还有很多其他成员没有默认构造函数,比如 DirectX 的 ID3D11Buffer * constantBuffer

【问题讨论】:

  • 那么Subset实际上有什么构造函数? Subset 到底是什么?
  • Subset 有复制构造函数吗?你能做类似的事情:subsets.push_back(new Subset(other.subsets[i])); ?

标签: c++ constructor copy-constructor deep-copy default-constructor


【解决方案1】:

如果您的Subset() 类有一个复制构造函数,那么您可以执行以下操作:

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.

如果您的Subset() 没有复制构造函数,那么您不能复制。

此外,您需要记住拥有~GeometryStructure() 才能从subset std::vector 中删除所有Subset() 对象

【讨论】:

  • 那么解决办法就是给没有默认构造函数的成员类添加拷贝构造函数?
  • 是的。只有这样,您才能根据需要进行“深拷贝”。 GeometryStructure(),以及它的所有成员,以及它的所有成员都必须拥有它。
【解决方案2】:

你正在制作一个深拷贝,所以你的循环应该是这样的

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

也就是说,您需要一个 复制构造函数 用于元素。即使Subset 有一个默认构造函数,你也不会用它复制任何东西。

【讨论】:

    【解决方案3】:

    怎么样:

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

    如果您实现复制和/或移动语义到您的子集类,您不需要创建构造函数,因为编译器将负责调用子集复制构造函数等。另一个好处是,当您的 Geometry 实例被破坏时,您无需担心破坏子集。

    【讨论】:

    • 我猜想将复制构造函数添加到成员类将需要更少的代码重组。无论如何,投了赞成票,因为它是一种替代解决方案。 :)
    • @oopscene 请注意,在这种情况下,除了需要重新组织代码之外,Subset 的默认构造函数的缺失将限制向量的使用,例如您将无法以给定的大小或resize() 构造它(检查类型要求)。
    猜你喜欢
    • 2012-09-01
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 2020-05-19
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    相关资源
    最近更新 更多