Tim0n
Tim0n

Reputation: 17

Confused about using constructurs with istream parameters

I have a slight problem when trying to learn how to create constructors.

I am currently learning c++ using the "C++ Primer" book and I've come to a point where I am told to create some constructors then change a code using these constructors. The exercise states that I should rewrite this program using the istream constructor but I don't know how to do this.

int main()
{
    Sales_data total; 
    if (read(cin,total))
    { 
        Sales_data trans; 
        while (read(cin,trans))
        {
            if (total.isbn() == trans.isbn())
            {
                total.combine(trans);
            }
            else
            {
                print(cout, total) << endl;
                total = trans;
            }
        }
        print(cout, total) << endl;
    }
    else
    {
        cerr << "No data?!" << endl;
    }    
    return 0;
}

The problem I have is, I have no idea how I am supposed to use an constructor using the istream, i thought it would be simple and just pass in cin as a default value but it does not work. from visual studios I get a "LNK2019" error and from code::blocks "undefined reference to Sales_data::read(std::istream&, Sales_data&)

My code in my header file looks like this:

struct Sales_data 
{
    Sales_data() = default;
    Sales_data(const std::string &s) : bookNo(s){}
    Sales_data(const std::string &s, unsigned n, double p) :
                    bookNo(s), units_sold(n), revenue(p*n){}
    Sales_data(std::istream &is) 
    {
         read(is, *this); 
    }

    std::string isbn() const { return bookNo; };
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
    Sales_data add(Sales_data&, Sales_data&);
    std::ostream &print(std::ostream&, const Sales_data&);
    std::istream &read(std::istream&, Sales_data&);

    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};

plus some definitions below.

and my cpp file looks like this:

int main()
{
    Sales_data total(cin); //results in error "LNK2019" or "undefined reference to Sales_data::read(std::istream&, Sales_data&)"

    if (1)
    { //not really sure what to use here but if I get my default value to work I might figure it out.
        // I'm thinking it should work with just cin >> total or read(total)
        Sales_data trans(cin); //results in error "LNK2019" or "undefined reference to         Sales_data::read(std::istream&, Sales_data&)"
        while (1)
        {
            if (total.isbn() == trans.isbn())
            {
                total.combine(trans);
            }
            else
            {
                print(cout, total) << endl;
                total = trans;
            }
        }
        print(cout, total) << endl;
    }
    else
    {
        cerr << "No data?!" << endl;
    }

    return 0;
}

I hope you understand my problem, and I appreciate all the help you provide! :)

Upvotes: 0

Views: 350

Answers (1)

Ben Cottrell
Ben Cottrell

Reputation: 6130

It sounds to me as if you're either missing some code from your book, or the book is expecting you to implement other functions and not just the constructor.

The linker error is telling you that it's unable to find an implementation of your read function, which should look like:

std::istream& Sales_data::read(std::istream&, Sales_data&)
{
    // TODO - implementation here.
}

It's also worth mentioning that function implementations should be added to the source (.cpp) file.

Upvotes: 1

Related Questions