0

I am working on a c++ program in Eclipse CDT. I am using the gcc compiler on Ubuntu 13. The program has two classes, Function, and Trial. In one line of the Trial class, I am trying to allocate an array of Functions using new. However, Eclipse is telling me that "type 'function' could not be resolved". What's weird, is that in the same method, creating an instance of Function with new does work. I've included all of the files in case they will be useful, though probably just the Trial.cpp will. The error is marked in the Trial::run method

Trial.cpp

#include "Trial.h"
#include "Function.h"
#include <string>
using namespace std;

Trial::Trial(long double* xs, long double* ys, int length, int popSize, double mutRate, int seed){
    this->xs=xs;
    this->ys=ys;
    this->length=length;
    this->popSize=popSize;
    this->mutRate=mutRate;
    this->seed=seed;
}
void Trial::run()
{
    Function* newArray =
            new Function[popSize]; //error here
    Function* f=new Function('x',0,0); //no error here
}


Trial::~Trial() {
    // TODO Auto-generated destructor stub
}

Trial.h

#ifndef TRIAL_H_
#define TRIAL_H_

#include "Function.h"

class Trial {
public:
    Trial(long double* xs, long double* ys, int length, int popSize, double mutRate, int seed);
    void run();
    virtual ~Trial();
private:
    long double* xs;
    long double* ys;
    int length;
    int popSize;
    double mutRate;
    int seed;
};

#endif /* TRIAL_H_ */

Function.h

#include <string>
#include <sstream>
using namespace std;

#ifndef FUNCTION_H_
#define FUNCTION_H_

class Function {
public:
    Function(char op, Function* l, Function* r);
    long double getValue(long double x);
    virtual ~Function();
    virtual string toString();
    static Function* makeFunction(int maxDepth);
    Function* clone();
    Function* breed(Function* other);
    void setNode(int i, Function* node);
    static double mutateChance;
    long double getFitness(long double* xs,long double* ys, int length);
private:
    Function* left;
    Function* right;
    char op;
    long double fitness;
    int getNumNodes();
    Function* getNode(int i);
    void mutate();
};

#endif /* FUNCTION_H_ */

Function.cpp //This is a long one, and probably not important

#include "Function.h"
#include <sstream>
#include <iostream>
#include <cmath>
#include <cstdlib>
#define NUMBER_WEIGHT 1
#define OP_WEIGHT 5
#define X_WEIGHT 5
#define NUM_SWAPS 3
#define TOTAL 39
//Total is 5*OP_WEIGHT+X_WEIGHT+9*NUM_WEIGHT
using namespace std;

double Function::mutateChance=.01;

bool isOp(char c)
{
    return c=='+'||c=='-'||c=='*'||c=='/'||c=='^';
}
Function::Function(char op, Function* l, Function* r) {
    this->left=l;
    this->right=r;
    this->op=op;
}

Function::~Function() {
    // TODO Auto-generated destructor stub
    delete left;
    delete right;
}

string Function::toString()
{
    stringstream stream;
    if(isOp(op))
    {
        stream<<'('<<left->toString()<<op<<right->toString()<<')';
    }
    else
    {
        stream<<op;
    }
    return stream.str();
}
long double Function::getValue(long double x)
{
    switch(op)
    {
    /*case '0'://Zeroes are stupid.  adding/subtracting does nothing.  Dividing makes an error or zero.  Multiplying makes 0.  exponentiation makes 1, 0 or an error.
        return 0;*/
    case '1':
        return 1;
    case '2':
        return 2;
    case '3':
        return 3;
    case '4':
        return 4;
    case '5':
        return 5;
    case '6':
        return 6;
    case '7':
        return 7;
    case '8':
        return 8;
    case '9':
        return 9;
    case 'x':
        return x;
    case '+':
        return left->getValue(x)+right->getValue(x);
    case '-':
        return left->getValue(x)-right->getValue(x);
    case '*':
        return left->getValue(x)*right->getValue(x);
    case '/':
        return left->getValue(x)/right->getValue(x);
    case '^':
        return pow(left->getValue(x),right->getValue(x));
    }
    return 0.0;
}
char toOp(int i)
{
    char c=(char)i;
    bool found=false;
    for(int i=1;i<=9;i++)
        if(c<i*NUMBER_WEIGHT)
        {
            c=i+48;
            found=true;
            break;
        }
    if(!found)
    {
        c-=9*NUMBER_WEIGHT;
        if(c<X_WEIGHT)
        {
            c='x';
            found=true;
        }
    }
    if(!found)
    {
        c-=X_WEIGHT;
        for(int i=1;i<=5;i++)
            if(c<i*OP_WEIGHT)
            {
                switch(i)
                {
                case 1:
                    c='+';
                    break;
                case 2:
                    c='-';
                    break;
                case 3:
                    c='*';
                    break;
                case 4:
                    c='/';
                    break;
                case 5:
                    c='^';
                    break;
                }
                break;
            }
    }
    return c;
}
Function* Function::makeFunction(int maxDepth)
{
    char c;//first are numbers, then x, then the operators, +-*/^
    if(maxDepth==0)
        c=rand()%(10*NUMBER_WEIGHT);
    else
        c=rand()%(10*NUMBER_WEIGHT+5*OP_WEIGHT);
    c=toOp(c);
    if(isOp(c))
        return new Function(c,makeFunction(maxDepth-1),makeFunction(maxDepth-1));
    else
        return new Function(c,0,0);
}
Function* Function::clone()
{
    if(isOp(op))
        return new Function(op,left->clone(),right->clone());
    else
        return new Function(op,0,0);
}
Function* Function::getNode(int i)
{
    if(i==0)
        return this;
    int l=left->getNumNodes();
    if(i<=l)
        return left->getNode(i-1);
    else
        return right->getNode(i-l-i);
}
void Function::setNode(int i, Function* node)
{
    node=node->clone();
    int l=left->getNumNodes();
    if(i==1)
        right=node;
    else if(i==l+1)
        left=node;
    else if(i<=l)
        left->setNode(i-1,node);
    else
        right->setNode(i-l-1,node);
}
int Function::getNumNodes()
{
    if(isOp(op))
        return 1+left->getNumNodes()+right->getNumNodes();
    else
        return 1;
}
double randDouble()
{
    return 1.*rand()/RAND_MAX;
}
void Function::mutate()
{
    if(isOp(op))
        do
            op=toOp(rand()%TOTAL);
        while(!isOp(op));
    else
        do
            op=toOp(rand()%TOTAL);
        while(isOp(op));
}
Function* Function::breed(Function* other)
{
    Function* child;//The mom is copied, then functions form the dad are switched in
    Function* dad;
    if(rand()%2)
    {
        child=this->clone();
        dad=other;
    }
    else
    {
        child=other->clone();
        dad=this;
    }
    int num=dad->getNumNodes();
    for(int i=0;i<NUM_SWAPS;i++)
        child->setNode(1+rand()%(child->getNumNodes()-1),dad->getNode(rand()%num));
    num=child->getNumNodes();
    for(int i=0;i<num;i++)
        if(randDouble()<mutateChance)
            child->getNode(i)->mutate();
    return child;
}

long double Function::getFitness(long double* xs, long double* ys, int length)
{
    long double total=0;
    for(int i=0;i<length;i++)
        total+=abs(ys[i]-this->getValue(xs[i]));
    total/=length;
    this->fitness=total;
    return total;
}
4

1 回答 1

0

new[]运算符需要一个公共默认构造函数。类Function不提供(因为Function有用户定义的构造函数,编译器不会自动生成默认构造函数)。改变它,它会工作。

顺便说一句,您不需要#include "Function.h"in Trial.h:不需要。

于 2013-08-02T15:48:55.273 回答