2013-08-02 379 views
0

我正在使用Eclipse CDT中的C++程序。我在Ubuntu 13上使用gcc编译器。该程序有两个类,Function和Trial。在Trial类的一行中,我试图用new来分配一个函数数组。但是,Eclipse告诉我“类型”功能无法解决。奇怪的是,在同一个方法中,使用new创建Function的实例确实有效。我已经包含了所有这些文件,以防它们有用,尽管可能只是Trial.cpp。该错误被标记在试运行::方法C++类型无法解析

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 //这是一个很长的,可能并不重要

#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; 
} 
+1

@juanchopanza什么?我看不到循环依赖。你在想什么圈子? – Walter

+0

@沃尔特我可以发誓我看过它。 – juanchopanza

回答

0

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

顺便说一句,你不需要#include "Function.h"Trial.h:这是不需要的。

+0

我可以用空指针初始化它吗? – BillThePlatypus

+0

谢谢你的方式。额外的包括是因为我在尝试一切。 – BillThePlatypus

+0

@BillThePlatypus不要尝试为'Function'指针使用空指针。 “Function”的默认构造函数最好设置成员来表示最普通的对象,即标识函数或空函数。 – Walter