构造、友元

来源:互联网 发布:国家博物馆淘宝 编辑:程序博客网 时间:2024/06/06 03:22



#include <cstdio>#include <string>#include <cstring>#include <iostream>#include <algorithm>using namespace std;class Sales_data{    //friend Sales_data add(const Sales_data &lsh, const Sales_data &rsh);public:    Sales_data() = default;    Sales_data(const string &s): bookNo(s){}    Sales_data(const string &s, unsigned n, double p):bookNo(s), units_sold(n), revenue(n*p){}    Sales_data(istream &);    string isbn() const{ return bookNo; }    Sales_data& combine(const Sales_data&);private:    double avg_price() const;    friend istream &read(istream&, Sales_data&);    friend ostream &print(ostream&, const Sales_data&);    string bookNo;    unsigned int units_sold = 0;    double revenue = 0.0;};Sales_data& Sales_data::combine(const Sales_data &rhs){    units_sold += rhs.units_sold;    revenue += rhs.revenue;    return *this;}double Sales_data::avg_price() const{    if(units_sold)        return revenue/units_sold;    return 0;}istream &read(istream &is, Sales_data &item){    double price = 0;    is >> item.bookNo >> item.units_sold >> price;    item.revenue = price * item.units_sold;    return is;}ostream &print(ostream &os, const Sales_data &item){    os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();    return os;}int main(){    printf("%s,%5.3s\n","computer","computer");    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;    }}

拷贝构造函数:如果一个构造函数第一个参数是自身类类型的引用,且任何额外参数都有默认值。使用已有的对象创建新的对象

class Sales_data{public:    Sales_data(const Sales_data&);//合成拷贝构造函数private:    string bookNo;    int units_sold = 0;    double revenue = 0.0;};Sales_data::Sales_data(const Sales_data &orig):bookNo(orig.bookNo),                    units_sold(orig.units_sold), revenue(orig.revenue){}

拷贝赋值运算符: operator=

赋值运算符通常应该返回一个指向其左侧运算对象的引用。将一个对象的值赋值给另一个已经存在的对象

class Foo{public:    Foo& operator=(const Foo&);//赋值运算符};


合成拷贝赋值运算符

Sales_data& Sales_data::operator=(const Sales_data &rhs){    bookNo = rhs.bookNo;    units_sold = rhs.units_sold;    revenue = rhs.revenue;    return *this;}


析构函数:释放对象的使用资源,并销毁对象的非static数据成员。不接受任何参数,不能被重载,一个类中只有一个析构函数。成员按照初始化的逆序销毁

class Foo{public:    ~Foo();//析构函数};


类的行为像一个值,意味着它也有自己的状态,当我们拷贝一个像值的对象是,副本和原对象是完全独立的

class HasPtr{public:    HasPtr(const std::string &s = std::string()):        ps(new std::string(s)), i(o){}    HasPtr(const HasPtr &p):        ps(new std::string(*p.s)), i(p.i){}    HasPtr& operator=(const HasPtr&);    ~HasPtr(){delete ps;}private:    std::string *ps;    int i;};HasPtr& HasPtr::operator=(const HasPtr &rhs){    auto newp = new string(*rhs.ps);    delete ps;    ps = newp;    i = rhs.i;    return *this;}

定义行为像指针的类

#include <iostream>#include <string>using namespace std;class HasPtr{public:    HasPtr(const std::string &s = std::string()):        ps(new std::string(s)), i(0), use(new int(1)){}    HasPtr(const HasPtr &p):        ps(new std::string(*p.ps)), i(p.i), use(p.use)        {            ++*use;        }    HasPtr& operator=(const HasPtr&);    ~HasPtr();    void getUse(){        cout << *this->use << endl;    }private:    std::string *ps;    int i;    int *use;};HasPtr::~HasPtr(){    if(--*use == 0){        delete ps;        delete use;    }}HasPtr& HasPtr::operator=(const HasPtr &rhs){    ++*rhs.use;    if(--*use == 0){        delete ps;        delete use;    }    ps = rhs.ps;    i = rhs.i;    use = rhs.use;    return *this;}int main(){    HasPtr p1("Hiya!");    HasPtr p2(p1);    HasPtr p3(p1);    p1.getUse();    p2.getUse();}


























0 0
原创粉丝点击