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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8011887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:50:50  来源:igfitidea点击:

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

c++object

提问by Lisa

I am trying to create multiple objects using a for loop, as eventually I will want this program to create different numbers of the class depending on my input. I tried to write this using an answer to a previous question. However, when I try to compile I get the error 'no matching function for call to 'Genes::Genes()'

我正在尝试使用 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;

}  

采纳答案by Aria Buckles

In C++, creating an array with new[] initializes all the objects with their default/no-parameter constructor.

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

So this line: (semicolon added)

所以这一行:(加分号)

 Genes *genes=new Genes[10];

Will result in ten calls to Genes::Genes().

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

That would normally seem fine, since C++ will give you a default constructor when you don't declare any. However, for this to happen, you must not declare any constructors. Your constructor:

这通常看起来没问题,因为当您不声明任何构造函数时,C++ 会给您一个默认构造函数。但是,要发生这种情况,您不得声明任何构造函数。你的构造函数:

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

Prevents the compiler from creating a default constructor for you, which in turn prevents you from making an array of Genes objects.

阻止编译器为您创建默认构造函数,从而阻止您创建 Genes 对象数组。



There are two reasonable solutions to this problem:

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

  1. You could add a default/no argument constructor to the Genes class. This is simple, but lacks some elegance. What is a default Genes object? If such an object made sense, you probably would have declared a default constructor already.

  2. Look into using std::vector instead of an array: http://www.cplusplus.com/reference/stl/vector/. While this is a more complicated fix in the short term, being familiar with the Standard Template Library (which supplies the vector class) will be valuable in the long term. That said, if you are just learning C++ and haven't seen templates before, this might be a bit overwhelming and you might want to read a bit about templates first. (for example, at http://www.learncpp.com/cpp-tutorial/143-template-classes/)

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

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

The vector class allows you to declare a capacity, for how many objects you will put into your array (or you may not declare a capacity, resulting in a slower insert). Then, it will only construct objects when they are placed into the vector. Your code would look something like this:

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

The last statement is (roughly) equivalent to:

最后一条语句(大致)等效于:

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

vector::push_back adds an item to the back of the vector and increases the vector capacity by 1: http://www.cplusplus.com/reference/stl/vector/push_back/

vector::push_back 在vector后面增加一个item,vector容量增加1:http: //www.cplusplus.com/reference/stl/vector/push_back/

You can subsequently access elements in the vector the same way as you would the array:

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

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

And you can query the size of the vector with vector::size():

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

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

回答by Kerrek SB

Use idiomatic C++ and pick the right container for the job (namely vector):

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

Now you have your elements in v[0], v[1], etc.

现在,你有你的元素v[0]v[1]等等。

回答by Martin Beckett

Genes *genes=new Genes[10]creates an array of 10 empty 'Genes' but you don't have a default constructor for Genes - there is no way of creating a 'Genes' without supplying a,b,c.

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

You need an empty ctor or supply a default arguement for 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) 

回答by Alok Save

Once you write a parameterized constructor,

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

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

the compiler does not generate the no parameter default constructor for your class, You need to provide it yourself.

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

You have two options:

您有两个选择:

. You need to define a default constructor for your class explicitly:

. 您需要为您的类明确定义一个默认构造函数:

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

Or

或者

. You use the paramertized constructor(with default arguments) instead of the default constructor.

. 您使用参数化构造函数(带有默认参数)而不是默认构造函数。

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

回答by Zeenobit

This is because you're first creating an array of Genes using the default constructor in the Genes* genes = new Genes[10]. What you need to do is use a standard container instead to store the genes in, such as std::vectoror std::list.

这是因为您首先使用Genes* genes = new Genes[10]. 您需要做的是使用标准容器来存储基因,例如std::vectorstd::list

回答by Clifford

There a number of solutions, the simplest to implement given what you have (i.e. without changing the class Genes, and without using a container class) is:

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

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

Then in the loop:

然后在循环中:

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

This has the advantage of avoiding a buffer overrun if geneno > 10.

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

Your access code (the cout stuff) is invalid in any case. Given the suggested change, accessing the object would look like:

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

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

The clean-up code would now also have to delete each object in the genes array before deleting the array itself. One reason why a container class may be more appropriate.

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