1
votes

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!

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
@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
You don't need to declare WAV_HEADER - you need to define it (by #including buffer.h). - Martin Bonner supports Monica

3 Answers

3
votes

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.

0
votes

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.

0
votes

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 .