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

How can I create multiple objects with for loop in C++?

本文关键字:创建 循环 对象 for c++      更新时间:2023-10-16

我试图使用for循环创建多个对象,因为最终我希望这个程序根据我的输入创建不同数量的类。我试着用前面一个问题的答案来写这篇文章。然而,当我尝试编译时,我得到错误'没有匹配函数调用'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;
}  

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

那么这行:(添加分号)

 Genes *genes=new Genes[10];

将导致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/。虽然这在短期内是一个更复杂的修复,但从长远来看,熟悉标准模板库(它提供vector类)将是有价值的。也就是说,如果你刚刚学习c++,以前没有见过模板,这可能会让你有点不知所措,你可能想先读一点关于模板的知识。(例如:http://www.learncpp.com/cpp-tutorial/143-template-classes/)

vector类允许您声明容量,用于将多少对象放入数组(或者您可以不声明容量,从而导致插入速度较慢)。然后,它只在对象放入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向vector的后面添加一项,并使vector的容量增加1:http://www.cplusplus.com/reference/stl/vector/push_back/

随后可以像访问数组一样访问vector中的元素:

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

可以用vector::size():

查询vector的大小
cout << "The vector has " << genes.size() << "elements" << endl;

使用惯用的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]

Genes *genes=new Genes[10]创建10个空'基因'的数组,但您没有基因的默认构造函数-没有提供a,b,c的情况下无法创建'基因'。

您需要为a、b、c提供一个空变量或默认实参

Genes::Genes() : cis(0),coding(0),effect(0)
or 
Genes::Genes(double a=0, double b=0, double c=0) 

一旦你写了一个参数化的构造函数,

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) 
{
}

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

有许多解决方案,最简单的实现给定你(即不改变类基因,不使用容器类)是:

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

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