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()'
#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;
}
Use idiomatic C++ and pick the right container for the job (namely 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.
In C++, creating an array with new[] initializes all the objects with their default/no-parameter constructor.
So this line: (semicolon added)
Genes *genes=new Genes[10];
Will result in ten calls to 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:
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.
There are two reasonable solutions to this problem:
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.
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/ )
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:
#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/
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():
cout << "The vector has " << genes.size() << "elements" << endl;
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.
You need an empty ctor or supply a default arguement for a,b,c
Genes::Genes() : cis(0),coding(0),effect(0)
or
Genes::Genes(double a=0, double b=0, double c=0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With