0

我尝试在 Xcode 上编译一个简单的程序并得到以下消息:

function<anonymous namespace>::Initialize' has internal linkage but is not defined

function<anonymous namespace>::HandleBadInput' has internal linkage but is not defined

Undefined symbols for architecture x86_64:
  "(anonymous namespace)::Initialize()", referenced from:
      _main in main.o
  "(anonymous namespace)::HandleBadInput()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

头文件如下所示:

#ifndef WJKErrorHandling
#define WJKErrorHandling

namespace WJKErrorHandling{

    void Initialize(void);
    int HandleBadInput(void);

}

#endif // defined(WJKErrorHandling)

实现文件如下所示:

#include <iostream>
#include "WJKErrorHandling.h"

namespace WJKErrorHandling{

    void Initialize(void){

        std::cin.exceptions(std::cin.failbit);
    }

    int HandleBadInput(void){

        std::cerr << "Input Error: wrong type?\n";
        std::cin.clear();

        char BadInput[5];
        std::cin >> BadInput;

        return 1;
    }

}

main.cpp 看起来像这样:

#include <iostream>
#include "WJKErrorHandling.h"


void Prompt (void){

    //Prompts the user to begin entering numbers

    std::cout << "Begin entering numbers: \n";
}

float GetNumber (void){

    std::cout << "Number: \n";
    float Number;
    std::cin >> Number;
    return Number;
    }

std::string GetString (void){

    std::cout << "String: \n";
    std::string String;
    std::cin >> String;
    return String;

}

int main()
{
    Prompt();
    WJKErrorHandling::Initialize();

    int ReturnCode = 0;

    try{

        float Number = GetNumber();
        std::cout << Number;
        std::string String = GetString();
        std::cout << String;

        std::cout << "SUCCESS!!!!\n";

    }
    catch(...){

        ReturnCode = WJKErrorHandling::HandleBadInput();
    }


    return ReturnCode;
}

到目前为止,我已经尝试找到答案,但我还没有理解我找到的任何帖子。我是 C++ 新手,所以任何帮助将不胜感激!

4

3 回答 3

4

您的 #define Guard 导致名称查找问题。

更改为以下样式应该可以解决问题:

#ifndef WJK_ERROR_HANDLING_H
#define WJK_ERROR_HANDLING_H
于 2012-11-23T23:41:18.103 回答
1

您还可以使用非标准但更惯用#pragma once的 ,根据其维基百科页面,所有主要编译器都支持它。

由于许多编译器具有识别包含防护的优化,因此两者之间没有速度优势。就我自己而言,我看到了以下优点#pragma once

  • 它只有一个含义(而定义服务于不同的目的)并且不会与其他事物发生冲突(例如,您的情况下的命名空间)。
  • 它很少打字,也很容易记住。
  • 您不会因为拼写错误(WJKERRORHANDLNG_H, ups 和 I 丢失)而出现错误,因为您将标头作为另一个副本开始并且忘记更改包含保护,这会给您带来相当讨厌的错误搜索会话。
于 2012-11-24T08:02:49.697 回答
0

事实证明这是一个糟糕的包含守卫:

#ifndef WJKErrorHandling
#define WJKErrorHandling

因为您稍后尝试将WJKErrorHandling其用作命名空间,但宏使它消失了。

将您的包含防护更改为:

#ifndef WJKERRORHANDLING_H
#define WJKERRORHANDLING_H

这可能更惯用,不太可能与某事发生冲突。

于 2012-11-23T23:41:48.043 回答