2013-11-09 5 views
1

Мой код компилируется в порядке. Но когда я пытаюсь использовать мой перегруженный оператор < < - сбой приложений. Я сам не нашел никаких решений. Если я не использую этот оператор, все работает отлично. Например, я могу передать отрицательный аргумент конструктору, и он покажет сообщение с использованием указателя данных класса «компания». Отладчик показывает, что программа выходит из строя на этой линии:Оператор перегрузки ошибок сегментации <<

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 вопрос, я надеюсь, что вы не возражаете, чтобы я спросил другого. Как я могу избежать использования включений в заголовках. Например, для перегруженного оператора < < Мне нужно включить iostream, потому что оно имеет возвращаемое значение типа ostream & и параметр того же типа. Заранее спасибо.

+0

Не знаете, почему вы пытаетесь избежать использования '# include' в заголовках. Это обычная практика. – godel9

+0

Я не знаю. Я где-то красный, что это не правильно, и лучше избегать такой практики. Так что это нормально, если я включил iostream в свой заголовок, а затем включил iostream в код, который использует мой заголовок? С этим не будет ничего плохого ??? –

+0

См. Ответ на [этот вопрос] (http://stackoverflow.com/questions/2596449/including-includes-in-header-file-vs-source-file) для лучшего объяснения, чем я могу вставить в комментарий. :-) – godel9

ответ

3

Когда вы объявляете массив:

Stock stocks[STKS] = ... 

элементы массива проиндексированы 0 через STKS - 1. При доступе к stocks[STKS] в этой строке:

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

вы обращаетесь к несуществующему элементу массива, который является причиной аварии. Учитывая контекст, вы, скорее всего, захотите std::cout<<stocks[st]; (tip tip: @gx_).

+0

Oh.Что глупо я. Смотрел код снова и снова и не заметил этой простой ошибки .... большое спасибо! –

+0

@FuzzyToozy Добро пожаловать. Поскольку вы новичок здесь, пожалуйста, не забудьте отметить принятый ответ, который помог большинству в решении проблемы. См. Также [Как принимает работу ответа] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)? – godel9

Смежные вопросы