//sales_data_class.h
class Sales_data
{
public:
//
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 &);
std::string isbn() const {return bookNo;}
Sales_data& combine( const Sales_data& );
private:
double avg_price() const;
//
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
}
//如果函数在概念上属于类但不定义在类中,一般应该和类声明(不是定义)在同一个头文件中
//一般来说,如果非成员函数是类接口的组成部分,则这些函数的声明应该和类在同一个文件中
Sales_data add( const Sales_data&, const Sales_data);
std::istream& read( std::istream&, const Sales_data);
std::ostream& print( std::ostream&, const Sales_data);
class与struct定义类的唯一区别在于第一个访问说明符(public、private)之前定义的成员的默认访问权限。对struct,定义在第一个访问说明符之前的成员是public,而class则是private。
友元
类可以运行其他类或者函数访问它的非公有成员,方法是友元(friend)。
//sales_data_class.h
struct Sales_data
{
//友元声明,类允许友元函数访问其的非公有成员
friend Sales_data add( const Sales_data&, const Sales_data&);
friend std::istream& read( std::istream&, Sales_data&);
friend std::ostream& print( std::ostream&, Sales_data&);
public:
//
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 &);
std::string isbn() const {return bookNo;}
Sales_data& combine( const Sales_data& );
private:
double avg_price() const;
//
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
}
//为使友元对类的用户可见,需要提供独立声明
Sales_data add( const Sales_data&, const Sales_data);
std::istream& read( std::istream&, const Sales_data);
std::ostream& print( std::ostream&, const Sales_data);
友元声明只能出现在类定义的内部,但具体位置不限。友元不是类的成员不受它所在区域访问控制级别的约束。
友元的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明。如果希望类的用户可以调用友元函数,必须在友元声明之外再专门对函数进行一次声明。
封装的优点有:1.确保用户代码不会无意间破坏封装对象的状态。2.被封装的类的具体实现细节可以随时改变,而无需调整用户级别的代码