【问题标题】:Unexpected error resloved by using <iostream> header使用 <iostream> 标头解决了意外错误
【发布时间】:2021-12-03 11:38:21
【问题描述】:

抱歉,如果此代码太长。当我试图重现这个问题时,它显示了预期的结果。

所以我试图制作一个 BigInteger 标题:

BIGINT.h

#ifndef BIGINT_H
#define BIGINT_H

//#include <iostream> 

#include <string>
#include <vector>
#include <cctype>
#include <cassert>
#include <cstddef>

extern short DEFAULT_BASE;

class BigInt
{
private:
    bool m_sign; // (0/false) mean negative, (1/true) mean positive
    std::string m_number;
    unsigned char m_base;

public:
    // constructor
    BigInt(std::string number = "0", unsigned char base = DEFAULT_BASE);
    BigInt(unsigned char base, std::string number = "0");
    BigInt(const BigInt &copy);

    //destructor
    ~BigInt();

    // get member value
    std::string number() const;
    unsigned char base() const;
    bool is_number_positive() const;

    // I/O overload
    friend std::ostream& operator<< (std::ostream& out, const BigInt& bigInt);
    friend std::istream& operator>> (std::istream& in, BigInt& bigInt);


};


#endif // BIGINT_H

BIGINT.cpp

#include "BIGINT.h"

short DEFAULT_BASE = 10;

// constructor
BigInt::BigInt(std::string number, unsigned char base)
{
{
    {
        int i{0};
        int numberOfSubtraction{0};
        while (number[i] == '-' || number[i] == '+')
        {
            numberOfSubtraction += number[i] == '-';
            ++i;
        }

        m_sign = numberOfSubtraction % 2 == 0;

        number = number.substr(i);
    }
    // std::cerr << base << ' ';
    assert(base >= 2 && base <= 36);
    for(char &i : number)
    {
        if(isdigit(i)) assert(i - '0' < base);
        else if(isalpha(i)) assert(i - 'A' + 10 < base);
        m_number += toupper(i);
    }
    m_base = base;


}

BigInt::BigInt(unsigned char base, std::string number)
{
    {
        int i{0};
        int numberOfSubtraction{0};
        while (number[i] == '-' || number[i] == '+')
        {
            numberOfSubtraction += number[i] == '-';
            ++i;
        }

        m_sign = numberOfSubtraction % 2 == 0;

        number = number.substr(i);
    }
    // std::cerr << base << ' ';
    assert(base >= 2 && base <= 36);
    for(char &i : number)
    {
        if(isdigit(i)) assert(i - '0' < base);
        else if(isalpha(i)) assert(i - 'A' + 10 < base);
        m_number += toupper(i);
    }
    m_base = base;

}

BigInt::BigInt(const BigInt &copy)
{
    m_number = copy.m_number;
    m_base = copy.m_base;
}

// destructor
BigInt::~BigInt() = default;

// get member value
std::string BigInt::number() const {return m_number;}
unsigned char BigInt::base() const {return m_base;}
bool BigInt::is_number_positive() const {return m_sign;}

// I/O overload
std::ostream& operator<< (std::ostream& out, const BigInt& bigInt)
{
    if(!bigInt.m_sign) out << '-';
    out << bigInt.m_number;

    return out;
}

std::istream& operator>> (std::istream& in, BigInt& bigInt)
{
    std::string number;
    in >> number;
    {
        int i{0};
        int numberOfSubtraction{0};
        while (number[i] == '-' || number[i] == '+')
        {
            numberOfSubtraction += number[i] == '-';
            ++i;
        }

        bigInt.m_sign = numberOfSubtraction % 2 == 0;

        number = number.substr(i);
    }
    for(char &i : number)
    {
        if(isdigit(i)) assert(i - '0' < DEFAULT_BASE);
        else if(isalpha(i)) assert(i - 'A' + 10 < DEFAULT_BASE);
        bigInt.m_number += toupper(i);
    }
    return in;
}

main.cpp

#include "BIGINT.h"

#include <iostream>
#include <string>

int main()
{
    BigInt bigInt{"+-+---+-+--+1", 10};
    std::cout << bigInt ;
}

所以我运行它,它断言: Assertion failed: base &gt;= 2 &amp;&amp; base &lt;= 36, file D:\phamngocphuc\C++ project\BigInt\BIGINT.cpp, line 49,这是出乎意料的,因为:

首先,它应该调用这个构造函数BigInt(std::string number = "0", unsigned char base = DEFAULT_BASE);

不是这个BigInt(unsigned char base, std::string number = "0");

而且我的基础实际上应该不错:(10 &gt;= 2 &amp;&amp; 10 &lt;= 36)true

其次,当我在 BIGINT.h 中的#include &lt;iostream&gt; 进行调试并运行它时,它实际上显示了-1,这是预期的结果。

那么为什么会这样呢?

【问题讨论】:

  • 你是如何编译该代码的?因为它甚至不应该在没有iostream 标头的情况下编译
  • @Konrad Rudolph 我在 main 中做了 include &lt;iostream&gt;,但在 BIGINT.h 中没有。请告诉我为什么不能编译
  • @justANewbie 但它需要包含在BiGINT.cpp中!请再次说明您是如何编译代码的。
  • @KonradRudolph:与 Code::Blocks 无关,只是标准包含做了一些其他包含/转发声明,不幸的是这些声明也被导出了:/ 模块应该可以解决这个问题。
  • @Jarod42 啊,对,我忽略了头文件中的其他包含。好的,所以 C::B 可能不是这里的罪魁祸首。

标签: c++ class c++11 constructor


【解决方案1】:

当您将有问题的构造函数标记为已删除时Demo

编译器点在哪里使用它,(它不是你想的):

问题出在:

std::ostream& operator<< (std::ostream& out, const BigInt& bigInt)
{
    if(!bigInt.m_sign) out << '-';
    out << bigInt.m_number;

    return out;
}

如果没有包含 &lt;iostream&gt;(似乎你有一些来自其他 std 包含的前向声明能够使用这些类型),out &lt;&lt; '-'; 刚刚被发现为候选 std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out, const BigInt&amp; bigInt)(虽然递归调用也会有问题)。

所以从'-' (BigInt(unsigned char base, std::string number = "0");) 构造一个BigInt

然后是你的错误。

【讨论】:

  • 非常感谢!顺便说一句,为什么这个断言会失败?
  • 因为'-' 不是有效的基数。
猜你喜欢
  • 2011-09-24
  • 1970-01-01
  • 2020-07-05
  • 1970-01-01
  • 2016-01-03
  • 2013-08-20
  • 2013-08-04
  • 1970-01-01
  • 2020-11-29
相关资源
最近更新 更多