我的目标是重载<<
运算符,以便将Param
类的对象适当地打印到标准输出。
该类Param
在globals.h
和globals.cpp
文件中定义。在这些文件下面,有一个main.cpp
测试程序。再下面是 3 个文本输入文件myparam__lb
、myparam__mid
和myparam_ub
。将所有这些文件放在同一个目录中,这是实际案例的缩小版本。
这是真实案例的回溯:
#0 0x00007ffff772811e in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x00007ffff7728829 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff7728c0f in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x0000000000450d32 in initSimulation5 () at ../simulation5.cpp:809
#4 0x000000000042c853 in Policy::Policy (this=0x7fffffffb090) at ../globals_mode.cpp:183
#5 0x00000000004325c4 in readPoliciesFromScript (policies=..., filename=...) at ../globals_utilities.cpp:321
#6 0x0000000000436280 in main (argc=1, argv=0x7fffffffe0d8) at ../main.cpp:122
此代码在另一台机器上正确运行,但在当前机器上,它出现了段错误。(两台机器都是 64 位 Ubuntu,但内核、Ubuntu 版本等不同)
问题:我的重载<<
运算符代码有什么问题?
全局变量.h
//globals.h
/* Initialize a Param object with the base file path to the
* text files containing the low, mid, and high estimates.
* If the low, mid, and high estimates are, respectively,
* stored in files
*
* ./input/myparam__lb
* ./input/myparam__mid
* ./input/myparam__ub
*
* then the base file path should be "./input/myparam".
*/
class Param {
public:
Param(string baseFilePath, const int size);
/*! Set Param to its low estimates */
void setLevelLow();
/*! Set Param to its mid estimates */
void setLevelMid();
/*! Set Param to its high estimates */
void setLevelHigh();
/*! Display range of Param values using an ostream */
friend ostream& operator<< (ostream &out, Param &cParam);
/*
* The overloaded operators below allow a Param object to be passed
* to a function as a (const|nonconst) std::vector<double>& and
* return a reference to the appropriate set of values based on
* whether the Param object is set to its low, mid, or high
* estimates.
*/
operator std::vector<double>& () {
if( level < 0 ) return lb;
if( level > 0 ) return ub;
return mid;
}
operator const std::vector<double>& () const {
if( level < 0 ) return lb;
if( level > 0 ) return ub;
return mid;
}
private:
int level;
std::vector<double> lb;
std::vector<double> mid;
std::vector<double> ub;
void readRatesFromFile(std::vector<double>& x, const string filePath, const int size);
};
全局变量.cpp
void Param::setLevelLow() { level = -1; }
void Param::setLevelMid() { level = 0; }
void Param::setLevelHigh() { level = 1; }
ostream& operator<< (ostream &out, Param &cParam) {
/* obtain correct level of parameter */
vector<double> *pParam;
switch(cParam.level) {
case -1:
pParam = &(cParam.lb);
out << "-";
break;
case 0:
pParam = &(cParam.mid);
out << "0";
break;
case 1:
pParam = &(cParam.ub);
out << "+";
break;
default:
std::cerr << "level=" << cParam.level << " when calling <<(ostream&,Param&)";
exit(1);
break;
}
/* obtain value(s) of parameter */
streamsize pre = cout.precision();
cout.precision(5);
out << " Value = ";
double smallest, largest;
smallest = *min_element(pParam->begin(), pParam->end());
largest = *max_element(pParam->begin(), pParam->end());
if(smallest==largest) {
out << smallest;
} else {
out << "[" << fixed << smallest << ", " <<
fixed << largest << "]";
}
cout.precision(pre);
}
Param::Param(string baseFilePath, const int size) {
/* Read lower-bound values from file */
readRatesFromFile(lb, baseFilePath+"__lb", size);
/* Read midpoint estimate values from file */
readRatesFromFile(mid, baseFilePath+"__mid", size);
/* Read upper-bound values from file */
readRatesFromFile(ub, baseFilePath+"__ub", size);
/* by default use midpoint estimate */
setLevelMid();
}
void Param::readRatesFromFile(std::vector<double>& x, const string filePath, const int size) {
char line[100];
x.clear();
x.resize(size,0.0);
fstream f_in(filePath.c_str(), ios::in);
if(f_in.fail()) {
cerr << "ERROR: Param::param() failed to open file \"" <<
filePath.c_str() << "\". Exiting...\n";
exit(1);
}
for(int i=0; i<size; ++i) {
f_in.getline(line,100);
x[i]=strtod(line,NULL);
}
f_in.close();
}
主文件
//main.cpp
#include <iostream>
#include "globals.h"
int main(int argc, char** argv) {
Param d("./myparam",3);
std::cout << d << "\n";
return 0;
}
我的参数__lb
0.13
0.24
0.45
myparam__mid
0.29
0.39
0.56
我的参数__ub
0.50
0.61
0.72