Drole
Drole

Reputation: 51

Error: 'class' does not name a type C++

I've seen many posts of this matter. But couldn't fix my problem anyhow.

My problem is that I want to send a bang from my class B to my class A. class A already got class B declared (B b;) but cant do the same in class B (A a;)

Seen that if class A includes class B. Then if class B includes class A it don't work. "A a does not name a type"

I'll show the code from my Metronome program.

This is the 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"

And here is the threadedObject class! Here I just want to send a "bang" to testApp

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

Showing the testApp.cpp aswell

#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!
}

So how can I use my bang() method from testApp.h in threadedobject.h?

Upvotes: 1

Views: 7502

Answers (1)

Walter
Walter

Reputation: 45414

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

Of course, you may only want one header and one source file.

EDIT

Of course, care must be taken that the pointers B::a and A::b are pointing to valid (fully constructed) objects.

Upvotes: 3

Related Questions