C++ 返回元组的错误
我一直试图用两个自定义类分数和整数重载+运算符。理想情况下,我希望+运算符返回操作的最简单版本(即1/4+3/4==1(整数))。我还没有找到一种动态分配返回类型的好方法,所以我尝试返回包含在结构或元组中的多个值。我在实际尝试main中的操作时遇到segfault,如下所示:C++ 返回元组的错误,c++,struct,segmentation-fault,tuples,tie,C++,Struct,Segmentation Fault,Tuples,Tie,我一直试图用两个自定义类分数和整数重载+运算符。理想情况下,我希望+运算符返回操作的最简单版本(即1/4+3/4==1(整数))。我还没有找到一种动态分配返回类型的好方法,所以我尝试返回包含在结构或元组中的多个值。我在实际尝试main中的操作时遇到segfault,如下所示: ///main///////// int main(){ Fraction *f = new Fraction(1,4); Fraction *f2 = new Fraction(3,4); Fraction
///main/////////
int main(){
Fraction *f = new Fraction(1,4);
Fraction *f2 = new Fraction(3,4);
Fraction *resF = new Fraction();//results
Integer *resI = new Integer();
boost::tie(resF, resI) = *f+*f2; //SEGFAULT here
}
所涉及的两个类是通用抽象基类的派生类,其成员和函数定义如下:
#include <boost/tuple/tuple.hpp>
#include <iostream>
//Number class
//forward declarations for tuple
class Integer;
class Fraction;
//abstract base class
template<class T>//T is derived class
class Number{
virtual const boost::tuple<Fraction*, Integer*> operator+ (const Number&) {};
virtual void display(std::ostream &) const {} ;
virtual bool operator==(const Number& rhs) const{} ;
};//end of Number class
//Integer class
class Integer: public Number<Integer>{
int numericValue;//<! the value of the integer
public:
int getValue() const;//<!access private member variable numericValue
void setValue(int);//<!set private member variable numericValue
Integer();//<!default constructor
Integer(int);//<!param constructor
virtual ~Integer() {}//<!destructor
//display
void display(std::ostream &) const;//<!stream a display of the number
//int == int
bool operator==(const Integer&) const;//<! comparator int-int
// int + int
const Integer operator+ (const Integer &);//<! add int+int
};
//DEFINITIONS////////////////////
//Default constructor
Integer::Integer(){
numericValue = 0;
}
// param constructor
Integer::Integer(int num){
numericValue = num;
}
//get integer value
int Integer::getValue() const{
return this->numericValue;
}
//set integer value
void Integer::setValue(int x){
this->numericValue = x;
}
//display int
void Integer::display(std::ostream& stream) const{
stream << this->numericValue<<std::endl;
}
// int + int
const Integer Integer::operator+(const Integer &rhs){
Integer temp = this->numericValue + rhs.numericValue;
return temp;
}
// int == int
bool Integer::operator==(const Integer& rhs) const{
if(this->numericValue == rhs.numericValue)
return true;
else
return false;
}
//end of Integer class
//Fraction class
class Fraction: public Number<Fraction>{
Integer numerator;
Integer denominator;
boost::tuple<Fraction*, Integer*> resOfAdd;
public:
int getNumerator();//<! to access private member
int getDenominator();//<! to access private member
bool isInteger;//<! flag if the fraction result of '+' can be reduced as an integer
bool isWhole();//!<tells if can be simplified to integer
Integer fToI;//<! store the integer value of the fraction if it is whole
Fraction() = default;//<! default constructor
Fraction(const int &, const int &);//<!param constructor
const Fraction simplify(const Fraction &in);//<! simplifies fraction if possible
int gcdCalculate(int lhs, int rhs);//!<greatest common denominator
int lcmCalculate(const int lhs, const int rhs);//<!least common
virtual ~Fraction() {}
//display
void display(std::ostream &) const;
// frac == frac
bool operator==(const Fraction& rhs) const;
//frac + frac
boost::tuple<Fraction*, Integer*> operator+(const Fraction &);
};//end of Fraction class
//DEFINITIONS///////////////////
// param constructor
Fraction::Fraction(const int & num, const int & den){
numerator.setValue(num);
denominator.setValue(den);
if(denominator.getValue()==1){//also an integer
fToI = Integer(numerator.getValue());
}
if(denominator.getValue() < 0 && numerator.getValue() > 0){//negative sign on bottom
denominator.setValue(denominator.getValue()*-1);
numerator.setValue(numerator.getValue()*-1); //switch it to the top
}
if(denominator.getValue() < 0 && numerator.getValue() < 0){//both top and bottom are negative
denominator.setValue(denominator.getValue()*-1);
numerator.setValue(numerator.getValue()*-1); //flip them to positive
}
}
//get ifInteger
bool Fraction::isWhole(){
return this->isInteger;
}
//get numerator
int Fraction::getNumerator(){
return this->numerator.getValue();
}
//get denominator
int Fraction::getDenominator(){
return this->denominator.getValue();
}
// display the fraction value
void Fraction::display(std::ostream & stream) const{
stream << this->numerator.getValue() << "/" << this->denominator.getValue()<<std::endl;
}
//simplify fraction
const Fraction Fraction::simplify(const Fraction &in){
int gcd = gcdCalculate(in.numerator.getValue(), in.denominator.getValue());
Fraction res = Fraction(in.numerator.getValue()/gcd, in.denominator.getValue()/gcd);
return res;
}
//lcm - least common multiplier
int Fraction::lcmCalculate(const int lhs, const int rhs){
int temp = gcdCalculate(lhs, rhs);
return temp ? (lhs / temp * rhs) : 0;
}
//gcd - greatest common divisor
int Fraction::gcdCalculate(int a, int b){
return b == 0 ? a : gcdCalculate(b, a % b);
}
//frac + frac -- causing problem
boost::tuple<Fraction*, Integer*>/*numRep<Fraction, Integer>*/ Fraction::operator+(const Fraction &rhsIn){
int numRes, denRes;
Fraction* resF;
Integer* resI; //if there is an integer result
//simplify input
Fraction lhs = simplify(*this);
Fraction rhs = simplify(rhsIn);
int lcm = lcmCalculate(lhs.denominator.getValue(), rhs.denominator.getValue());
int gcd = gcdCalculate(lhs.denominator.getValue(), rhs.denominator.getValue());
//share denominator?
if(lhs.denominator.getValue() == rhs.denominator.getValue()){
numRes = lhs.numerator.getValue() + rhs.numerator.getValue();//simply add the numerators
denRes = lhs.denominator.getValue();//keep denominator
}
else{
// a1 a2 a1*b2+a2*b1
// -- + -- = -----------
// b1 b2 b1*b2
int a1 = lhs.getNumerator();
int b1 = lhs.getDenominator();
int a2 = rhs.numerator.getValue();
int b2 = rhs.denominator.getValue();
numRes = a1*b2 + a2*b1;
denRes = b1*b2;
}
*resF = Fraction(numRes, denRes);
//simplify
*resF = simplify(*resF);
if(resF->denominator.getValue() == 1){//integer result
resF->isInteger = true;//flag
fToI = Integer(resF->numerator.getValue());//make Integer
resI = &fToI; //return the integer when you can
}
else{
resI = new Integer(0);
}
//put the fraction and the (possible) integer representations into a number struct
resOfAdd = boost::make_tuple(resF, resI);
std::cout<<" + = ";
resF->display(std::cout);
delete resF;
delete resI;
return resOfAdd;
}
#包括
#包括
//数字类
//元组的前向声明
类整数;
类分数;
//抽象基类
模板//T是派生类
班号{
虚拟常量boost::元组运算符+(常量编号&){};
虚拟空显示(std::ostream&)const{};
虚拟布尔运算符==(常量编号和rhs)常量{};
};//数字课结束
//整数类
类整数:公共编号{
int numericValue;//numericValue;
}
//设置整数值
void Integer::setValue(int x){
此->数值=x;
}
//显示整数
void Integer::display(std::ostream&stream)常量{
流numericValuenumericValue==rhs.numericValue)
返回true;
其他的
返回false;
}
//整数类的结束
//分数类
类别分数:公众号码{
整数分子;
整数分母;
boost::tuple resofad;
公众:
int getNumerator();//运算符+(常量分数&);
};//分数课结束
//定义///////////////////
//参数构造函数
分数::分数(常数整数和数值,常数整数和数值){
分子。设置值(num);
分母设定值(den);
如果(denominator.getValue()==1){//也是一个整数
fToI=整数(分子.getValue());
}
如果(分母.getValue()<0&&numerator.getValue()>0){//底部的负号
Denominor.setValue(Denominor.getValue()*-1);
numerator.setValue(numerator.getValue()*-1);//将其切换到顶部
}
如果(分母.getValue()<0&&numerator.getValue()<0){//顶部和底部都是负数
Denominor.setValue(Denominor.getValue()*-1);
numerator.setValue(numerator.getValue()*-1);//将其翻转为正数
}
}
//获取ifInteger
布尔分数::isWhole(){
返回此->isInteger;
}
//得到分子
整数分数::getNumerator(){
返回此->分子.getValue();
}
//得到分母
int分数::getDenominator(){
返回此->分母.getValue();
}
//显示分数值
空隙率::显示(标准::ostream&stream)常数{
流分子.getValue()分子.getValue());//生成整数
resI=&fToI;//可以时返回整数
}
否则{
resI=新整数(0);
}
//将分数和(可能的)整数表示形式放入数字结构中
resOfAdd=boost::make_tuple(resF,resI);
标准::cout
resf
是一个未初始化的指针,您正在尝试将某个内容复制并分配到它所指向的位置
在这里返回指针是个坏主意,因为它引入了所有权语义。仅按值返回:
boost::tuple<Fraction, Integer> ...
boost::tuple。。。
如果使用指针,则可以指示是否存在整数,请考虑使用<代码> Boo::可选< /COD> .< /P>请张贴您的SeStError究竟发生在哪里?我很惊讶您没有得到未使用的变量警告。您似乎还有很多不必要的指针。“要添加的分数和结果都是这样声明的”在哪里<代码>*resF=分数(numRes,denRes)代码>取消对默认初始化指针的引用,该指针的值不确定!非常糟糕!您正在返回
resOfAdd
,但它从未声明过。是什么类型的?谢谢!这是一个很好的建议,解决了我的问题。感谢大家的洞察力和帮助。
boost::tuple<Fraction, Integer> ...