2013-04-29 2 views
1

이 문제에 대한 많은 게시물을 보았습니다. 그러나 어쨌든 내 문제를 해결할 수 없습니다.오류 : 'class'의 유형이 C++이 아닙니다.

내 문제는 클래스 B에서 클래스 A로 클래스를 보내고 싶습니다. 클래스 A는 이미 클래스 B (B b;)로 선언되었지만 클래스 B (A a;)에서는 동일하게 수행합니다.

클래스 A에 클래스 B가 포함되어있는 경우를 봅니다. 클래스 B에 클래스 A가 포함되어 있으면 작동하지 않습니다. "A는 형식을 지정하지 않습니다"

나는 내 메트로놈 프로그램에서 코드를 보여줄 것이다.

이것은 testApp.h

#ifndef TESTAPP_H_ 
#define TESTAPP_H_ 
#pragma once 

#include "ofMain.h" 
#include "ofxSimpleGuiToo.h" 
#include "ofxSynth.h" 
#include "threadedObject.h" 

class testApp : public ofBaseApp{ 

public: 
// virtual string getName() { return "testApp"; } 
    testApp(){ 

    } 
    ofxSynth synth; 

    threadedObject TO; 

    void setup(); 
    void update(); 
    void draw(); 
    int count; 
    int rate; 
    int last_time; 
    void audioOut(float *input, int bufferSize, int nChannels); 

    ofSoundStream soundstream; 
    //testApp(); 
    friend void bang(); 
    void keyPressed (int key); 
    void keyReleased(int key); 
    void mouseMoved(int x, int y); 
    void mouseDragged(int x, int y, int button); 
    void mousePressed(int x, int y, int button); 
    void mouseReleased(int x, int y, int button); 
    void windowResized(int w, int h); 
    void dragEvent(ofDragInfo dragInfo); 
    void gotMessage(ofMessage msg); 
    ofEventArgs eventA; 


    int mainAppsCount; 

    void bang(){ 
     synth.trigger(); 
    } 
private: 
    int bpm; 
    int current_bpm; 

    float current_frequency; 
    float frequency; 
    float volume; 



}; 
#endif 

#ifndef THREADED_OBJECT_H 
#define THREADED_OBJECT_H 
#pragma once 
#include "ofMain.h" 
#include "testApp.h" 

입니다 그리고 여기 threadedObject 클래스입니다! 여기에 난 그냥 testApp.cpp이

#include "testApp.h" 

static const int bufferSize = 512; 
static const int sampleRate = 44100; 
//-------------------------------------------------------------- 
void testApp::setup(){ 

volume = 0.5f; 
gui.addTitle("Master volume"); 
gui.addSlider("Volume", volume, 0.5f, 1.f); 
frequency = current_frequency = 0.1f; 
gui.addTitle("Base Frequency"); 
gui.addSlider("frequency", frequency, 20.f, 2000.f); 

bpm=current_bpm; 
bpm=135; 
gui.addTitle("Metronome"); 
gui.addSlider("Bpm", bpm, 40.f, 140.f); 
mainAppsCount = 0; 
TO.start(); 
gui.show(); 
synth.setSampleRate(sampleRate); 
soundstream.setup(this, 2, 0, sampleRate, bufferSize, 4); 
} 
//-------------------------------------------------------------- 
void testApp::update(){ 
if(current_frequency != frequency) 
{ 
    synth.setFrequency(frequency); 
    current_frequency = frequency; 
} 

synth.setVolume(volume); 

mainAppsCount++; 
TO.bpm(bpm); 
} 
//-------------------------------------------------------------- 
void testApp::draw(){ 
ofSetHexColor(0xffffff); 
TO.draw(); 

string str = "I am a the main opengl thread.\nmy current count is: "; 
str += ofToString(mainAppsCount); 
ofDrawBitmapString(str, 350, 256); 


ofSetHexColor(0xff0033); 

ofDrawBitmapString("press 's' to stop the thread and 'a' to start it", 250, 360); 
gui.draw(); 
} 

//-------------------------------------------------------------- 
void testApp::keyPressed(int key){ 
if (key == 'a'){ 
    TO.start(); 
} else if (key == 's'){ 
    TO.stop(); 
} 
} 


void testApp::audioOut(float * output, int bufferSize, int nChannels) 
{ 
synth.audioOut(output, bufferSize, nChannels, 0); 
} 
//-------------------------------------------------------------- 
void testApp::mousePressed(int x, int y, int button){ 
    bang(); #The bang is in testApp.h. for just triggering the synth to play! 
} 

그래서 어떻게 threadedobject.h에 testApp.h에서 내 뱅() 메소드를 사용할 수 있습니다 aswell보기

class threadedObject : public ofThread { 
public: 
    testApp ta; #HERE IS THE FAIL 

    ofRectangle posRect; 
    int count; 
    int count2; 
    friend void bang(); 
    double bpmToSeconds; 
    double changedBpm; 
    double sum; 
    int counter; 
    int check; 
    //-------------------------- 
    threadedObject(){ 
     // testApp hej; 
     count = 1; 
     count2=0; 
     bpmToSeconds=60; 
     changedBpm=135; 
     sum = bpmToSeconds/changedBpm; 
     counter=0; 

    } 
    //-------------------------- 
    void start(){ 
     startThread(true, false); 
    } 
    //-------------------------- 
    void stop(){ 
     stopThread(); 
    } 
    //-------------------------- 
    void threadedFunction(){ 

     while(isThreadRunning() != 0){ 
      if(lock()){ 
       count++; 
       if(count>4) count= 1; 
       unlock(); 
       counter++; 
       ofSleepMillis(getBpm() * 1000); 
      } 
     } 
    } 
    //-------------------------- 
    void bpm(double bpm) 
    { 
     changedBpm=bpm; 
     sum = bpmToSeconds/changedBpm; 
    } 
    //-------------------------- 
    double getBpm(){ 
     return sum; 
    } 
    //-------------------------- 
    void draw(){ 

     string str = "I am a slowly increasing thread. \nmy current count is: "; 
     string tick = " TICK!"; 
     string tock = " TOCK!"; 
     posRect.set(150, 150, 0, 0); 
     if(lock()){ 
      str += ofToString(count); 
      if(counter%4==0){ 
      str += tock; 
      }else { 
       str += tick; 
      #Here i want to send a bang to testApp like ta.bang(); 
      } 
      unlock(); 
     }else{ 
      str = "can't lock!\neither an error\nor the thread has stopped"; 
     } 
     ofDrawBitmapString(str, 350, 156); 
    } 
    int getTick() 
    { 
     return counter; 
    } 
}; 
#endif 

TestApp가

에 "쾅"를 보내려면 ?

+5

[this] (http://stackoverflow.com/questions/16205367/two-template-classes-being-composed-of-a-emember-of-each-other)를 읽으십시오. –

+0

그래, 포인터/참조를 사용해야한다고 알았어 이 경우 testApp * ta; 하지만 어떻게 사용합니까? ta-> bang(); ta.bang(); 내가 ta-> bang()을 할 때; 나는 이것을 얻는다 : 오류 : '((threadedObject *) this) -> threadedObject :: ta'에 'bang'회원 요청, 비 클래스 유형 'testApp *'| – Drole

+0

'threadedObject' 클래스의 정의 앞에'class testApp;'선언을 넣어야합니다. 'ta'가 포인터이기 때문에'ta-> bang();을 사용하십시오. 다시 한 번, 다른 질문에 대한 나의 설명에주의를 기울이십시오. 클래스 A의 정의 앞에 'B'라는 선언이 나옵니다. –

답변

3

A.h :

class B; // forward decl 
class A { 
    B*b; 
public: 
    void bang(); 
    void send(); 
    /* ... */ 
}; 

B.h :

class A; // forward decl 
class B { 
    A*a; 
public: 
    void bang(); 
    void send(); 
    /* ... */ 
}; 

A.cc

#include A.h 
#include B.h 
void A::bang() { /* ... */ } 
void A::send() 
{ 
    b->bang(); 
} 

B.cc

#include B.h 
#include A.h 
void B::bang() { /* ... */ } 
void B::send() 
{ 
    a->bang(); 
} 
O

물론 헤더 파일 하나와 소스 파일 하나만 있으면됩니다. 물론

편집

는주의를 B::aA::b 유효를 가리키는 포인터가 객체 (완전 구성) 않도록주의해야합니다.

+0

작동했습니다! 일종의! 때 void B :: send() { a-> bang(); } A에서 강타를 유발합니다.하지만, 만약 내가 bang()에 코드를 넣는다면 그것은 훌륭하다. void bang() { cout << "Hello"<< endl; // this works 카운터 ++; // 작동하지 않습니다 (충돌) synth.trigger(); // 작동하지 않습니다. (크래시) } – Drole

+0

@Drole 회원 포인터 'a'와'b'가 가리키는 객체가 유효합니까 (완전히 구성되었는지)? 그렇지 않다면,'counter;'는 접근하기에 유효하지 않을 수 있습니다. 질문에서 크래시 코드의 간단한 예를 제공하십시오. – Walter

관련 문제