为什么我不能在 header 文件中定义全局函数?
why cant I define a global function in a header file?
我有这个功能,我试图在我的 header 中定义,其中我还定义了一个 class,但由于某种原因,这是不可能的,因为我不明白为什么它造成了很多问题。
database.h
//#pragma once
#ifndef DATABASE_H
#define DATABASE_H
#include "record.h"
#include "spectogram.h"
#include <iostream>
#include <experimental/filesystem>
#define string_dir_to_test_files "/home/noob/soundcloud/src/include/database/test_files/"
class database {
public:
vector<AudioFile<SAMPLE>> list_of_files;
database();
};
int number_of_files(std::experimental::filesystem::path path);
#endif DATABASE_H
database.cpp
#include "database.h"
int number_of_files(std::experimental::filesystem::path path)
{
using std::experimental::filesystem::directory_iterator;
return std::distance(directory_iterator(path),directory_iterator(path));
}
database::database()
{
std::experimental::filesystem::path _path(string_dir_to_test_files);
if (std::experimental::filesystem::exists(_path))
{
std::cout << "exists() = " << std::experimental::filesystem::exists(_path) << "\n"
<< "root_name() = " << _path.root_name() << "\n"
<< "root_path() = " << _path.root_path() << "\n"
<< "relative_path() = " << _path.relative_path() << "\n"
<< "parent_path() = " << _path.parent_path() << "\n"
<< "filename() = " << _path.filename() << "\n"
<< "stem() = " << _path.stem() << "\n"
<< "extension() = " << _path.extension() << "\n";
std::cout << "Number of files in directory: " << number_of_files(_path) << std::endl;
}
}
spectogram.h
#pragma once
#include <sigpack.h>
#include "AudioFile.h"
#include <iostream>
typedef float SAMPLE;
class spectogram {
public:
spectogram();
arma::mat generate_spectogram(const AudioFile<SAMPLE> *file)
{
arma::mat output;
if(file->getNumChannels() == 2)
{
std::cout << "I am here" << std::endl;
arma::Col<SAMPLE> ch1 = file->samples[0];
arma::Col<SAMPLE> ch2 = file->samples[1];
arma::mat output = sp::specgram(ch1);
return output;
}
else
{
std::cout << "I am am here" << std::endl;
arma::Col<SAMPLE> ch1 = file->samples[0];
arma::mat output = sp::specgram(ch1);
std::cout << output << std::endl;
return output;
}
}
};
record.h 包含的音频文件是这个 one
#pragma once
#include <iostream> // Functionality: COUT
#include "portaudio.h"
#include <stdio.h>
#include <stdlib.h>
#include <chrono> //Functionality: Sleep
#include <thread> //Functionality: Sleep
#include <algorithm> //Functionality: fill_n
#include "AudioFile.h"
#define SAMPLE_RATE (44100)
typedef float SAMPLE;
#define NUM_SECONDS 10
#define NUM_CHANNELS 1
#define SAMPLE_SILENCE 0.0f
#define PA_SAMPLE_TYPE paFloat32
#define FRAMES_PER_BUFFER (512)
#define TRUE (1==1)
#define FALSE (!TRUE)
#define WRITE_TO_FILE TRUE
typedef struct
{
int frameIndex;
int maxFrameindex;
SAMPLE *recordedSamples;
}
paTestData;
class record {
public:
record();
void start_record();
AudioFile<SAMPLE> file;
private:
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
int recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData);
static int recordCallbackSub(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
auto pThis = reinterpret_cast<record*>(userData); // get back the this pointer.
return pThis->recordCallback( inputBuffer, outputBuffer,framesPerBuffer, timeInfo,statusFlags, nullptr);
}
};
match.h
#pragma once
#include <iostream>
class match {
public:
};
main.cpp
#include <record.h>
#include <database.h>
#include <match.h>
#include <spectogram.h>
#include <iostream>
int main()
{
database start;
//record somethis;
//somethis.start_record();
//spectogram specto;
//specto.generate_spectogram(&somethis.file);
return 0;
}
给我这些警告:
make
[ 42%] Built target project_portaudio
[ 57%] Built target record
[ 68%] Built target spectogram
[ 78%] Built target database
Scanning dependencies of target match
[ 84%] Building CXX object src/include/match/CMakeFiles/match.dir/match.cpp.o
[ 89%] Linking CXX static library libmatch.a
[ 89%] Built target match
Scanning dependencies of target cmakeDemo
[ 94%] Building CXX object src/CMakeFiles/cmakeDemo.dir/main.cpp.o
In file included from /home/noob/soundcloud/src/main.cpp:2:0:
/home/noob/soundcloud/src/include/database/database.h:25:8: warning: extra tokens at end of #endif directive [-Wendif-labels]
#endif DATABASE_H
^~~~~~~~~~
[100%] Linking CXX executable ../cmakeDemo
[100%] Built target cmakeDemo
但如果 #include<match.h>
被评论,警告会移除吗?
make
[ 42%] Built target project_portaudio
[ 57%] Built target record
[ 68%] Built target spectogram
[ 78%] Built target database
[ 89%] Built target match
[100%] Built target cmakeDemo
有什么地方很奇怪吗?
问题是你缺少 header 守卫。每次包含 header 时,它都被视为函数的重新定义。
您应该在 header 的开头添加 #pragma once
以解决此问题
根据您的输出,我在这里看到一个警告:
In file included from /home/noob/soundcloud/src/main.cpp:2:0:
/home/noob/soundcloud/src/include/database/database.h:25:8: warning: extra tokens at end of #endif directive [-Wendif-labels]
#endif DATABASE_H
^~~~~~~~~~
在 database.h 的末尾,#endif
预处理器在末尾有一个额外的 DATABASE_H
标记。 #endif
不接受任何额外的令牌,因此将其删除:
...
#endif
我有这个功能,我试图在我的 header 中定义,其中我还定义了一个 class,但由于某种原因,这是不可能的,因为我不明白为什么它造成了很多问题。
database.h
//#pragma once
#ifndef DATABASE_H
#define DATABASE_H
#include "record.h"
#include "spectogram.h"
#include <iostream>
#include <experimental/filesystem>
#define string_dir_to_test_files "/home/noob/soundcloud/src/include/database/test_files/"
class database {
public:
vector<AudioFile<SAMPLE>> list_of_files;
database();
};
int number_of_files(std::experimental::filesystem::path path);
#endif DATABASE_H
database.cpp
#include "database.h"
int number_of_files(std::experimental::filesystem::path path)
{
using std::experimental::filesystem::directory_iterator;
return std::distance(directory_iterator(path),directory_iterator(path));
}
database::database()
{
std::experimental::filesystem::path _path(string_dir_to_test_files);
if (std::experimental::filesystem::exists(_path))
{
std::cout << "exists() = " << std::experimental::filesystem::exists(_path) << "\n"
<< "root_name() = " << _path.root_name() << "\n"
<< "root_path() = " << _path.root_path() << "\n"
<< "relative_path() = " << _path.relative_path() << "\n"
<< "parent_path() = " << _path.parent_path() << "\n"
<< "filename() = " << _path.filename() << "\n"
<< "stem() = " << _path.stem() << "\n"
<< "extension() = " << _path.extension() << "\n";
std::cout << "Number of files in directory: " << number_of_files(_path) << std::endl;
}
}
spectogram.h
#pragma once
#include <sigpack.h>
#include "AudioFile.h"
#include <iostream>
typedef float SAMPLE;
class spectogram {
public:
spectogram();
arma::mat generate_spectogram(const AudioFile<SAMPLE> *file)
{
arma::mat output;
if(file->getNumChannels() == 2)
{
std::cout << "I am here" << std::endl;
arma::Col<SAMPLE> ch1 = file->samples[0];
arma::Col<SAMPLE> ch2 = file->samples[1];
arma::mat output = sp::specgram(ch1);
return output;
}
else
{
std::cout << "I am am here" << std::endl;
arma::Col<SAMPLE> ch1 = file->samples[0];
arma::mat output = sp::specgram(ch1);
std::cout << output << std::endl;
return output;
}
}
};
record.h 包含的音频文件是这个 one
#pragma once
#include <iostream> // Functionality: COUT
#include "portaudio.h"
#include <stdio.h>
#include <stdlib.h>
#include <chrono> //Functionality: Sleep
#include <thread> //Functionality: Sleep
#include <algorithm> //Functionality: fill_n
#include "AudioFile.h"
#define SAMPLE_RATE (44100)
typedef float SAMPLE;
#define NUM_SECONDS 10
#define NUM_CHANNELS 1
#define SAMPLE_SILENCE 0.0f
#define PA_SAMPLE_TYPE paFloat32
#define FRAMES_PER_BUFFER (512)
#define TRUE (1==1)
#define FALSE (!TRUE)
#define WRITE_TO_FILE TRUE
typedef struct
{
int frameIndex;
int maxFrameindex;
SAMPLE *recordedSamples;
}
paTestData;
class record {
public:
record();
void start_record();
AudioFile<SAMPLE> file;
private:
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
int recordCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData);
static int recordCallbackSub(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData)
{
auto pThis = reinterpret_cast<record*>(userData); // get back the this pointer.
return pThis->recordCallback( inputBuffer, outputBuffer,framesPerBuffer, timeInfo,statusFlags, nullptr);
}
};
match.h
#pragma once
#include <iostream>
class match {
public:
};
main.cpp
#include <record.h>
#include <database.h>
#include <match.h>
#include <spectogram.h>
#include <iostream>
int main()
{
database start;
//record somethis;
//somethis.start_record();
//spectogram specto;
//specto.generate_spectogram(&somethis.file);
return 0;
}
给我这些警告:
make
[ 42%] Built target project_portaudio
[ 57%] Built target record
[ 68%] Built target spectogram
[ 78%] Built target database
Scanning dependencies of target match
[ 84%] Building CXX object src/include/match/CMakeFiles/match.dir/match.cpp.o
[ 89%] Linking CXX static library libmatch.a
[ 89%] Built target match
Scanning dependencies of target cmakeDemo
[ 94%] Building CXX object src/CMakeFiles/cmakeDemo.dir/main.cpp.o
In file included from /home/noob/soundcloud/src/main.cpp:2:0:
/home/noob/soundcloud/src/include/database/database.h:25:8: warning: extra tokens at end of #endif directive [-Wendif-labels]
#endif DATABASE_H
^~~~~~~~~~
[100%] Linking CXX executable ../cmakeDemo
[100%] Built target cmakeDemo
但如果 #include<match.h>
被评论,警告会移除吗?
make
[ 42%] Built target project_portaudio
[ 57%] Built target record
[ 68%] Built target spectogram
[ 78%] Built target database
[ 89%] Built target match
[100%] Built target cmakeDemo
有什么地方很奇怪吗?
问题是你缺少 header 守卫。每次包含 header 时,它都被视为函数的重新定义。
您应该在 header 的开头添加 #pragma once
以解决此问题
根据您的输出,我在这里看到一个警告:
In file included from /home/noob/soundcloud/src/main.cpp:2:0:
/home/noob/soundcloud/src/include/database/database.h:25:8: warning: extra tokens at end of #endif directive [-Wendif-labels]
#endif DATABASE_H
^~~~~~~~~~
在 database.h 的末尾,#endif
预处理器在末尾有一个额外的 DATABASE_H
标记。 #endif
不接受任何额外的令牌,因此将其删除:
...
#endif