【问题标题】:why cant I define a global function in a header file?为什么我不能在头文件中定义全局函数?
【发布时间】:2017-11-16 18:40:25
【问题描述】:

我有这个函数,我试图在我的头文件中定义一个类,但由于某种原因,这是不可能的,因为我不明白为什么它会导致这么多问题。

数据库.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

数据库.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&lt;match.h&gt; 被评论,警告会删除?

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

有什么很奇怪的吗?

【问题讨论】:

  • 你没有显示你的真实代码。
  • @manni66 我添加了完整的代码,有些东西似乎很奇怪.. 删除 #include 会删除警告 => 该文件为空,那么为什么还要引起问题呢?跨度>
  • 突然间错误消失了,只剩下一个警告......

标签: c++ function header redefinition


【解决方案1】:

问题是你缺少头部保护。每次包含标题时,它都被视为对函数的重新定义。 你应该在标题的开头添加#pragma once 来解决这个问题

【讨论】:

  • 对不起...我的头文件确实有标题保护...忘记在上面的代码中添加它。对不起。不过建议很好。
  • 可能是构建系统处理文件的问题。值得尝试 #ifndef 只是为了测试它与 #pragma once 限制无关。
  • 显示的代码不需要包含守卫。但它也不会产生引用的错误。这个答案只是一个猜测。
  • 我添加了完整的代码,有些东西似乎很奇怪.. 删除 #include&lt;match.h&gt; 删除了警告 => 该文件为空,为什么还要引起问题? @PeteBecker
  • 我添加了完整的代码,有些东西似乎很奇怪.. 删除 #include 会删除警告 => 该文件是空的,那么为什么还会导致问题呢? @OriBen-Shir
【解决方案2】:

根据您的输出,我在这里看到一个警告:

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

【讨论】:

  • 是的...不知道为什么要添加...修复它...谢谢:)
猜你喜欢
  • 2021-01-14
  • 2013-09-04
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 2011-08-30
相关资源
最近更新 更多