如何在C ++中使用for循环创建多个对象?

时间:2011-11-04 15:40:41

标签: c++ object

我正在尝试使用for循环创建多个对象,因为最终我希望这个程序根据我的输入创建不同数量的类。我尝试使用之前question的答案来写这个。但是,当我尝试编译时,我得到错误'没有匹配函数来调用'Genes :: Genes()'

#include <iostream>
#include <cstdlib>
#include <ctime> 

using namespace std;

float random();

class Genes{
 public:
 double cis;
 double coding;
 double effect;
 Genes(double a, double b, double c);
};

Genes::Genes(double a, double b, double c) 
{
  cis=a;
  coding=b;
  effect=c;
};

int main()
{
  int geneno, i;

  srand(time(NULL));

  geneno=4; //this will probably be cin later

  Genes *genes=new Genes[10]

  for(i=0;i<=geneno;i++){
    double d,e,f;

    d=random();
    e=random();
    f=random();

    genes[i]=Genes(d,e,f);

    cout<<"cis is "<<genes.cis<<'\n';
    cout<<"coding is "<<genes.coding<<'\n';
    cout<<"Effect for gene is "<<genes.effect<<'\n';

    }
 delete[] genes;
 }


float random(){

  float decRANDMAX;

 decRANDMAX=RAND_MAX*1.0;

 return rand()%(RAND_MAX+1)/decRANDMAX;

}  

6 个答案:

答案 0 :(得分:10)

使用惯用的C ++并为作业挑选合适的容器(即vector):

#include <vector>

const std::size_t num_genes; // your data here

//...

std::vector<Genes> v;
v.reserve(num_genes);

for (std::size_t i = 0; i != num_genes; ++i)
{
  v.push_back(Genes(random(), random(), random()));  // old-style
  v.emplace_back(random(), random(), random());      // modern (C++11)
}

现在,您的元素位于v[0]v[1]

答案 1 :(得分:8)

在C ++中,使用new []创建数组会使用默认/无参数构造函数初始化所有对象。

所以这一行:(分号补充)

 Genes *genes=new Genes[10];

将导致十次调用Genes :: Genes()。

这通常看起来很好,因为当你没有声明任何内容时,C ++会给你一个默认的构造函数。但是,为此,您不得声明任何构造函数。你的构造函数:

Genes::Genes(double a, double b, double c)

阻止编译器为您创建默认构造函数,这反过来又阻止您创建Genes对象数组。


这个问题有两种合理的解决方案:

  1. 您可以向Genes类添加默认/无参数构造函数。这很简单,但缺乏优雅。什么是默认的Genes对象?如果这样的对象有意义,你可能已经声明了一个默认的构造函数。

  2. 使用std :: vector而不是数组:http://www.cplusplus.com/reference/stl/vector/。虽然这在短期内是一个更复杂的解决方案,但熟悉标准模板库(提供矢量类)将是长期有价值的。也就是说,如果您刚刚学习C ++并且以前没有看过模板,这可能有点压倒性,您可能想先阅读一些关于模板的内容。 (例如,在http://www.learncpp.com/cpp-tutorial/143-template-classes/

  3. vector类允许您声明一个容量,表示您将在阵列中放入多少个对象(或者您可能不会声明容量,从而导致插入速度变慢)。然后,它只会在将对象放入向量时构造对象。您的代码看起来像这样:

    #include <vector> // to get the vector class definition
    using std::vector; // to 
    
    vector<Genes> genes;
    genes.reserve(geneno); // optional, but speeds things up a bit
    
    for(i = 0; i <= geneno; i++) {
        double d = random();
        double e = random();
        double f = random();
    
        genes.push_back(Genes(d, e, f));
    }
    

    最后一个陈述(大致)等同于:

    Genes temp(d, e, f);
    genes.push_back(temp);
    

    vector :: push_back在向量的后面添加一个项目,并将向量容量增加1:http://www.cplusplus.com/reference/stl/vector/push_back/

    您可以随后以与数组相同的方式访问向量中的元素:

    cout << "The third gene's coding is " << genes[3].coding << endl;
    

    您可以使用vector :: size()查询向量的大小:

    cout << "The vector has " << genes.size() << "elements" << endl;
    

答案 2 :(得分:3)

Genes *genes=new Genes[10]创建一个包含10个空“基因”的数组,但是你没有基因的默认构造函数 - 没有提供a,b,c就无法创建'基因'。

您需要一个空的ctor或为a,b,c

提供默认辩论
Genes::Genes() : cis(0),coding(0),effect(0)

or 

Genes::Genes(double a=0, double b=0, double c=0) 

答案 3 :(得分:1)

编写参数化构造函数后,

Genes::Genes(double a, double b, double c);

编译器不会为您的类生成无参数默认构造函数,您需要自己提供它。

您有两种选择:

。您需要明确定义类的默认构造函数:

Genes::Genes():cis(0),coding(0),effect(0)
{
}

。您可以使用参数化构造函数(使用默认参数)而不是默认构造函数。

Genes::Genes(double a=0, double b=0, double c=0) 
{
}

答案 4 :(得分:0)

这是因为你首先使用Genes* genes = new Genes[10]中的默认构造函数创建一个Genes数组。您需要做的是使用标准容器来存储基因,例如std::vectorstd::list

答案 5 :(得分:0)

有许多解决方案,最简单的实现方式(即不更改类Genes,不使用容器类)是:

geneno = 4;
Genes** genes = new Genes*[geneno] ;

然后在循环中:

genes[i] = new Genes(d,e,f);

这具有避免缓冲区溢出的优点,如果geneno> 10。

您的访问代码(cout内容)无论如何都无效。鉴于建议的更改,访问对象将如下所示:

cout<<"cis is "<<genes[i]->cis<<'\n';
cout<<"coding is "<<genes[i]->.coding<<'\n';
cout<<"Effect for gene is "<<genes[i]->.effect<<'\n';

在删除数组本身之前,清理代码现在还必须删除基因数组中的每个对象。容器类可能更合适的一个原因。