1

I have the following classes:

// Buffer.cpp

#include "MonoSample.h"
#include "Buffer.h"

#define INBUFFERSIZEBLOCK   1024                // input block size
#define MAXBUFFERSIZE       1000000             // max buffer size (1MB)

#pragma warning (disable : 4996)

using std::endl;
using std::fstream;


Buffer::Buffer()
{
}
(...)

// Buffer.h

#pragma once
#include <string>

using std::string;

typedef struct  WAV_HEADER              
{    
uint8_t         RIFF[4];    
uint32_t        ChunkSize;    
uint8_t         WAVE[4];    
uint8_t         fmt[4];    
uint32_t        Subchunk1Size;      
uint16_t        audioFormat;            
uint16_t        numOfChan;          
uint32_t        samplesPerSec;    
uint32_t        bytesPerSec;
uint16_t        blockAlign;    
uint16_t        bitsPerSample;    
uint8_t         Subchunk2ID[4];    
uint32_t        sampledDataLen;    
} wavHdr, *pwavHdr;


class Buffer
{

private:
    string         wFileNamePath;                   
    int                  nChannel;                  
    wavHdr                  head;                   
    unsigned long     samplesLen;                   
    unsigned long     samplesPte;               
    FILE*                wavFile;               
    MonoSample*      firstSample;       

public:

    Buffer();
    Buffer(string filePath, int id);    
    ~Buffer();

    wavHdr              getHeader();    // retorna el header del fitxer wav
    string         getWavFileName();    // retorna el nom del fitxer wav
    int                     getNumChannel();    // retorna el id del fitxer wav
    bool              ResetBuffer();    // inicia el bufer
    void              closeBuffer();    // allibera la memoria del buffer
    bool  openFile(string p, int n);    // obre fitxer
    MonoSample*    getFirstSample();    // punter a la primera mostra mono  
    MonoSample*    getSample(int n);    // pointer to 16 bits of the mono sample n
};

// main.cpp

#include "Buffer.cpp"
#include "MonoSample.h"
#include <iostream> 

using namespace std;

#define NUMCANALS 16

int main()
{
(...)
}

When I run my program I get the following errors:

Severity Code Description Project File Line Suppression State Error LNK2005 "public: class MonoSample * __cdecl Buffer::getSample(int)" (?getSample@Buffer@@QEAAPEAVMonoSample@@H@Z) already defined in Buffer.obj

Severity Code Description Project File Line Suppression State Error LNK2005 "public: class MonoSample * __cdecl Buffer::getFirstSample(void)" (?getFirstSample@Buffer@@QEAAPEAVMonoSample@@XZ) already defined in Buffer.obj

(...)

I think it is due the fact that in the main.cpp I write #include "Buffer.cpp" but I don't know how to do it without that #include... How can I use Buffer objects if I don't have this #include?

Thank you!

crende
  • 21
  • 3
  • You are right about where the problem is. Include `buffer.h` instead of `buffer.cpp`? A .cpp file needs only the declaration of types/functions, the definition can be in a separate file. – DeiDei Nov 04 '16 at 11:04
  • @DeiDei: He probably wants the *definitions* of the types - but just the *declarations* of functions. (Which is what the header gives. A declaration of WAV_HEADER would look like `struct WAV_HEADER;`.) – Martin Bonner supports Monica Nov 04 '16 at 11:06
  • You don't need to declare WAV_HEADER - you need to define it (by #including buffer.h). – Martin Bonner supports Monica Nov 04 '16 at 12:07

3 Answers3

3

Main should start

#include "Buffer.h"

So that it has the definition of the class (but not the definition of all the member functions). You almost never want to #include .cpp files.

This will produce further errors because you use types in Buffer.h that you haven't defined there. The fix for this is to define them by putting

#include "MonoSample.h"

at the start of Buffer.h.

  • I would say *never* include .cpp files. *"Almost"* adds a lot of meaning to it. – DeiDei Nov 04 '16 at 11:05
  • 1
    There are advanced preprocessor techniques which involve included source files. One approach is to call them .inl files. Another is to call them .cpp (which means your editor understands them). – Martin Bonner supports Monica Nov 04 '16 at 11:08
  • Thanks @MartinBonner When I change #include "Buffer.h" instead of "Buffer.cpp" I get lots of errors of my Buffer.h class: Error C2143 syntax error: missing ';' before '' Error C2143 syntax error: missing ';' before '' Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int Error C2238 unexpected token(s) preceding ';' What should I do? – crende Nov 04 '16 at 11:24
  • 1
    @crende: `#include "MonoSample.h"` in Buffer.h, which uses that type. – Lightness Races in Orbit Nov 04 '16 at 11:31
  • @MartinBonner thank you!! Do I need to add also struct WAV_HEADER in the private atributs of the declaration of Buffer class in Buffer.h ? – crende Nov 04 '16 at 12:08
  • @crende: No. `wavHdr header;` is just another (shorter) way of saying `struct WAV_HEADER header;` (or `WAV_HEADER header;`), and you already have that. – Martin Bonner supports Monica Nov 04 '16 at 12:12
0

I think it is due the fact that in the main.cpp I write #include "Buffer.cpp"

Yes.

I don't know how to do it without that #include... How can I use Buffer objects if I don't have this #include?

Your Visual Studio project has "main.cpp" and "Buffer.cpp" in it. The two are linked together during build. C++ typically has a two-phase build process: first compilation, then linking.

As long as your "main.cpp" knows about Buffer and WAV_HEADER during compilation, that's enough (this is what you achieve with your #include "Buffer.h"). Linkage takes care of the rest.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

After compilation, the linker will merge the obj files . You have the same symbol defined multiple times in different translation ("One Definition Rule" violated here) Put the definition of your class in a separate file which does not contain also the definitions of the member functions of that class; then, let buffer.cpp and main.cpp include that file .

Cherkesgiller
  • 520
  • 4
  • 17