g++ 两个关于头文件编译问题

好吧,不得不说Professor Demko的C++ for FE 的project真是可以加速学习C++的好方法。当年本科时候在李文新老师的课上学C++最后也只是完成了POJ上《魔兽世界》的大作业,而且只考虑了下派生类、友类和虚构函数。其他东西,呵呵,早都忘了噜。

好了,废话不多说,开始讨论问题。

在 terminal中用g++编译C++文件,遇到两个主要的问题,中文网页中很少有所讨论。卤煮在stackoverflow上倒是看到了不少这样的讨论,果然程序员的英文水平都很高>w<

  1. 头文件中类的构建函数

楼主将一个正态函数生成及相关计算的类写入了一个头文件,该头文件在其他文件和主文件中都会被调用。

头文件的代码如下

 1 #ifndef _NORMDISTINTEGRAL_H__
 2 #define _NORMDISTINTEGRAL_H__
 3 
 4 /* Generate Normal Distribution */
 5 
 6 #include <iostream>
 7 #include <cmath>
 8 
 9 const double PI = 3.1415926;
10 
11 class MyNormDist
12 {
13     double mean; // the mean of Normal Distribution
14     double std_v; // standard deviation
15     public:
16     MyNormDist(double mean_, double std_v_);
17     ~MyNormDist();
18     double Norm_pdf(double x); // probability density function
19     double Norm_cdf(double x); // cumlative distribution function
20     double Norm_igral(const double& low_b, const double& up_b); // integral
21 };
22 
23 #endif

与头文件同名的cpp文件中代码如下,主要对头文件类中的函数内容进行编写。

 1 #include "NormDistIntegral.h"
 2 
 3 using namespace std;
 4 
 5 MyNormDist::MyNormDist(double mean_, double std_v_)
 6 {
 7     mean = mean_;
 8     std_v = std_v_;
 9 }
10 
11 //MyNormDist::~MyNormDist(){}
12 
13 /* 省略以下描述函数代码 */

单独对该cpp文件进行g++编译是完全没有问题的。但是对主文件进行编译时(关联其他o文件),遇到了如下的问题。

Undefined symbols for architecture x86_64:

"MyNormDist::~MyNormDist()", referenced from:
___tcf_2 in CashFlow.o
___tcf_1 in BSE.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

好吧,他说我析构函数没有找到。stackoverflow上给的解答是,析构函数的函数内容也应该在cpp文件中写出,而不应该省去。因为头文件仅仅是对类及类中得变量、函数进行声明。实际调用还是应该从cpp文件中调用的,因此就算析构函数没有具体内容,也应该在cpp文件中写出,即把上一段代码中第11行的注释dashes给去掉。

references:http://stackoverflow.com/questions/11488486/undefined-symbols-for-architecture-x86-64-compiling-inherited-class?rq=1

  2. 文件调用

楼主还为主文件编写了个cpp文件getCMT.cpp,其中包含函数 getCMT() 以冀在主文件main.cpp和CashFlow.cpp中直接调用。可是编译主文件时,又报出了如下的错误

ld: duplicate symbol getCMT()
in CashFlow
.o and main.o for architecture x86_64

collect2: ld returned 1 exit status

好吧,stackoverflow上给出的答案是,在多个其他cpp文件中直接用引用cpp文件时候,该cpp文件因为被多个文件include,这些文件的o文件都会得到这个函数的复制件。C++是禁止对同一函数进行多次定义的,linker可能会对此报错。

如何解决了,建议将这些函数体写到一个cpp文件中,并建立一个与cpp文件同名的的头文件,头文件仅仅对cpp文件中得函数进行声明。在其他文件中需要引用该函数的时候,include该头文件即可。

Reference:http://stackoverflow.com/questions/9299676/ld-duplicate-symbol

 

 

 

posted @ 2013-10-05 11:52  cwss  阅读(2729)  评论(2编辑  收藏  举报