【问题标题】:Segmentation fault overloading operator <<分段错误重载运算符 <<
【发布时间】:2013-11-21 18:41:43
【问题描述】:

我的代码编译得很好。但是当我尝试使用我的重载运算符

os << "Company: " << s.company

在函数中:

std::ostream& operator<<(std::ostream& os, const Stock& s)
{
using std::ios_base;
// set format to #.###
ios_base::fmtflags orig =
    os.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize prec = os.precision(3);

os << "Company: " << s.company
    << "  Shares: " << s.shares << '\n';
os << "  Share Price: $" << s.share_val;
// set format to #.##
os.precision(2);
os << "  Total Worth: $" << s.total_val << '\n';

// restore original format
os.setf(orig, ios_base::floatfield);
os.precision(prec);
return os;
}

代码如下:

// stock20.h -- augmented version
#ifndef STOCK20_H_
#define STOCK20_H_
#include <iostream>
class Stock
{
private:
char* company;
int shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
Stock();        // default constructor
Stock(const char* co, long n = 0, double pr = 0.0);
~Stock();       // do-nothing destructor
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
const Stock & topval(const Stock & s) const;
friend std::ostream& operator<<(std::ostream& os, const Stock& s);
};

#endif

实现:

// stock20.cpp -- augmented version
#include "stock20.h"
#include <cstring>

#define my_delete(x){ delete[] x; x = NULL; }
using namespace std;
// constructors
Stock::Stock()        // default constructor
{
company = new char[1];
company[0] = '\0';
shares = 0;
share_val = 0.0;
total_val = 0.0;
}

Stock::Stock(const char* co, long n, double pr)
{
  company = new char[strlen(co)+1];
  strcpy(company,co);

if (n < 0)
{
    std::cout << "Number of shares can't be negative; "
               << company << " shares set to 0.\n";
    shares = 0;
}
else
    shares = n;
share_val = pr;
set_tot();
}

// class destructor
Stock::~Stock()        // quiet class destructor
{
  my_delete(company);
}

// other methods
void Stock::buy(long num, double price)
{
 if (num < 0)
{
    std::cout << "Number of shares purchased can't be negative. "
         << "Transaction is aborted.\n";
}
else
{
    shares += num;
    share_val = price;
    set_tot();
}
}

void Stock::sell(long num, double price)
{
using std::cout;
if (num < 0)
{
    cout << "Number of shares sold can't be negative. "
         << "Transaction is aborted.\n";
}
else if (num > shares)
{
    cout << "You can't sell more than you have! "
         << "Transaction is aborted.\n";
}
else
{
    shares -= num;
    share_val = price;
    set_tot();
}
}

void Stock::update(double price)
{
share_val = price;
set_tot();
}

std::ostream& operator<<(std::ostream& os, const Stock& s)
{
using std::ios_base;
// set format to #.###
ios_base::fmtflags orig =
    os.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize prec = os.precision(3);

os << "Company: " << s.company
    << "  Shares: " << s.shares << '\n';
os << "  Share Price: $" << s.share_val;
// set format to #.##
os.precision(2);
os << "  Total Worth: $" << s.total_val << '\n';

// restore original format
os.setf(orig, ios_base::floatfield);
os.precision(prec);
return os;
}

const Stock & Stock::topval(const Stock & s) const
{
if (s.total_val > total_val)
    return s;
else
    return *this; 
}

以及代码用法:

// usestok2.cpp -- using the Stock class
// compile with stock20.cpp
#include "stock20.h"

const int STKS = 4;
int main()
{{
//create an array of initialized objects
    Stock stocks[STKS] = {
    Stock("NanoSmart", 12, 20.0),
    Stock("Boffo Objects", 200, 2.0),
    Stock("Monolithic Obelisks", 130, 3.25),
    Stock("Fleep Enterprises", 60, 6.5)
    };

std::cout << "Stock holdings:\n";
int st;
for (st = 0; st < STKS; st++)
    std::cout<<stocks[STKS]; //here we got an error
// set pointer to first element
const Stock * top = &stocks[0];
for (st = 1; st < STKS; st++)
    top = &top->topval(stocks[st]);
// now top points to the most valuable holding
std::cout << "\nMost valuable holding:\n";
std::cout<<*top;}
// std::cin.get();
return 0; 
}

如果因为我问了 1 个问题,我希望你不介意我问另一个问题。我怎样才能避免在标题中使用包含。例如,对于重载的 operator

【问题讨论】:

  • 不知道为什么要避免在标题中使用#include。这是正常的做法。
  • 我不知道。我在某处发红,这不是正确的做法,最好避免这种做法。所以如果我在我的标题中包含 iostream 然后我在使用我的标题的代码中包含 iostream 就可以了吗?这样不会有什么不好???
  • 查看this question 的答案以获得比我可以放入评论更好的解释。 :-)

标签: c++ c overloading


【解决方案1】:

当你声明一个数组时:

Stock stocks[STKS] = ...

数组元素的索引为0 到STKS - 1。当您在此行访问stocks[STKS] 时:

std::cout<<stocks[STKS]; // Out-of-bounds: STKS > STKS - 1

您正在访问导致崩溃的不存在的数组元素。鉴于上下文,您可能想要 std::cout&lt;&lt;stocks[st]; 代替(帽子提示:@gx_)。

【讨论】:

  • 哦。我真笨。一遍又一遍地看代码,没有注意到那个简单的错误……非常感谢!
  • @FuzzyToozy 不客气。由于您是新来的,请不要忘记将最有助于解决问题的答案标记为已接受。另见How does accepting an answer work?
猜你喜欢
  • 1970-01-01
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
相关资源
最近更新 更多