重载运算符后的 C++ 链接器错误

C++ linker error after overloading an operator

当我尝试从 C++ 如何编程、Deitel 和 Deitel 编译示例程序时,我不断收到以下错误。我用了 g++ Fig11_05.cpp -o Fig11_05

我花了几个小时试图通过查找 Internet 尤其是 Whosebug 来解决这个问题,但无济于事!

我尝试使用不同的命令行参数,例如 -libstd=libc++、-std=c++11、-std=c++14

我不断收到的错误是这样的: 未定义的体系结构符号 x86_64: "operator<<(std::__1::basic_ostream >&, PhoneNumber const&)",引用自: _main Fig11_05-1f04bd.o "operator>>(std::__1::basic_istream >&, PhoneNumber&)",引用自: _main Fig11_05-1f04bd.o ld:未找到体系结构的符号 x86_64 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

g++ -v的结果:

配置为:--prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10 .12.sdk/usr/include/c++/4.2.1 苹果 LLVM 版本 8.0.0 (clang-800.0.42.1) 目标:x86_64-apple-darwin15.6.0 线程模型:posix 安装目录:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

代码:

// Fig. 11.3: PhoneNumber.h                                                                                                                                   
// PhoneNumber class definition                                                                                                                               
#ifndef PHONENUMBER_H
#define PHONENUMBER_H

#include <iostream>
#include <string>


class PhoneNumber
{
  friend std::ostream& operator<<(std::ostream&, const PhoneNumber&);
  friend std::istream &operator>>(std::istream&, PhoneNumber&);
private:
  std::string areaCode; // 3-digit area code                                                                                                                  
  std::string exchange; // 3-digit exchange                                                                                                                   
  std::string line; // 4-digit line                                                                                                                           
}; // end class PhoneNumber                                                                                                                                   

#endif

// Fig. 11.4: PhoneNumber.cpp                                                                                                                                 
// Overloaded stream insertion and stream extraction operators                                                                                                
// for class PhoneNumber.                                                                                                                                     
#include <iomanip>
#include "PhoneNumber.h"
using namespace std;

// overloaded stream insertion operator; cannot be                                                                                                            
// a member function if we would like to invoke it with                                                                                                       
// cout << somePhoneNumber;                                                                                                                                   
ostream& operator<<(ostream& output, const PhoneNumber& number)
{
   output << "Area Code: "  << number.areaCode << "\nExchange: "
          << number.exchange << "\nLine: " << number.line << "\n"
          << "(" << number.areaCode << ") " << number.exchange << "-"
          << number.line << "\n";;
   return output; // enables cout << a << b << c;                                                                                                             
} // end function operator<<                                                                                                                                  

// overloaded stream extraction operator; cannot be                                                                                                           
// a member function if we would like to invoke it with                                                                                                       
// cin >> somePhoneNumber;                                                                                                                                    
istream& operator>>(istream& input, PhoneNumber& number)
{
   input.ignore(); // skip (                                                                                                                                  
   input >> setw(3) >> number.areaCode; // input area code                                                                                                    
   input.ignore(2); // skip ) and space                                                                                                                       
   input >> setw(3) >> number.exchange; // input exchange                                                                                                     
   input.ignore(); // skip dash (-)                                                                                                                           
   input >> setw(4) >> number.line; // input line                                                                                                             
   return input; // enables cin >> a >> b >> c;                                                                                                               
} // end function operator>>   


// Fig. 11.5: fig11_05.cpp                                                                                                                                    
// Demonstrating class PhoneNumber's overloaded stream insertion                                                                                              
// and stream extraction operators.                                                                                                                           
#include <iostream>
#include "PhoneNumber.h"
using namespace std;

int main()
{
   PhoneNumber phone; // create object phone                                                                                                                  

   cout << "Enter phone number in the form (123) 456-7890:" << endl;

   // cin >> phone invokes operator>> by implicitly issuing                                                                                                   
   // the global function call operator>>( cin, phone )                                                                                                       
   cin >> phone;

   cout << "\nThe phone number entered was:\n";

   // cout << phone invokes operator<< by implicitly issuing                                                                                                  
   // the global function call operator<<( cout, phone )                                                                                                      
   cout << phone << endl;
} // end main       

注意:我最近安装然后卸载了CUDA工具包8。我需要更新版本的Xcode,所以我安装了Xcode最新版本的8.2 .1,并将旧版本保存在不同的目录中以防万一。不过,我认为问题不在于 Xcode 的安装。另外,当我安装 CUDA 时,我必须将 DYLD_LIBRARY_PATH 设置为一个目录。但是,这可能不是问题的根源!我只是想帮助你找出问题来帮助我解决它:)

提前致谢!你真是个好社区!

您尝试构建程序:

g++ Fig11_05.cpp -o Fig11_05

不成功,因为你忽略了编译,link进入 编写包含函数定义的代码:

std::ostream& operator<<(std::ostream& output, const PhoneNumber& number)

和:

std::istream& operator>>(std::istream& input, PhoneNumber& number)

由您的程序调用。这就是为什么 linker 说:

Undefined symbols for architecture x86_64: 
"operator<<(std::__1::basic_ostream >&, PhoneNumber const&)", referenced from: _main in Fig11_05-1f04bd.o 
"operator>>(std::__1::basic_istream >&, PhoneNumber&)", referenced from: _main in Fig11_05-1f04bd.o 
...

改为这样做:

g++ Fig11_05.cpp PhoneNumber.cpp -o Fig11_05

或完整说明过程:-

将源文件 Fig11_05.cpp 编译为目标文件 Fig11_05.o:

$ g++ -o Fig11_05.o -c Fig11_05.cpp

将源文件 PhoneNumber.cpp 编译为目标文件 PhoneNumber.o:

$ g++ -o PhoneNumber.o -c PhoneNumber.cpp

Link目标文件Fig11_05.oPhoneNumber.o进入程序Fig11_05

$ g++ -o Fig11_05 Fig11_05.o PhoneNumber.o

然后您可以 运行:

./Fig11_05

这里是a fairly good beginner's tutorial 关于使用 GCC 构建 C 或 C++ 程序。