C++ Primer 第七章 7.2 练习和总结

访问说明符可以控制类中的成员的访问权限。

使用public修饰的类的成员,类的用户可以直接访问。

使用private修饰的类的成员,只有成员函数可以访问,类的用户是没法访问的。

C++没有限制类中定义访问说明符的数量和位置,可以随处添加,一个访问说明符的修饰范围是,它声明的位置开始到类的下一个访问说明符。

C++中有两个关键字可以定义类,就是class和struct,他们的唯一区别在于class定义类的默认的访问权限是private,struct定义的类默认的访问权限是public。

练习

7.16
没有数量和位置的限制,如果成员函数或者数据成员需要让类的使用者显式的使用,那么就是用public访问说明符,一般情况下,数据成员都是private,还有一些仅在类内部使用的函数也可以使用private访问限定符修饰

7.17
默认的访问权限不一样

7.18

封装就是隐藏细节,封装可以让用户无需关注类的实现细节,直接调用接口。这还在一定程度上保证了类的安全性,让类的使用者不能直接修改某些数据成员。

7.19

struct Person {
private:
	string name;
	string address;
public:
	string get_info()const{
		return "name:" + name + "\n address:" + address;
	}

	Person(const string &n, const string &address) :name(n), address(address) {};
};

为了防止用户随意修改数据成员,所以数据成员都使用private访问限定符

而成员函数则使用public。

7.2.1 友元

一般情况下,数据成员会声明为private,这样在使用类的代码时,用户时无法直接访问数据成员的。

但是对于某些函数,它是类的接口,却不是类的成员,这些类往往会直接访问类的数据成员。为了解决在类的外部无法访问private修饰的数据成员和成员函数。

C++提供了友元friend

如果把一个函数在类中声明为友元,那么这个函数就可以直接访问了类的private修饰的成员了。

就像这样。


struct Person {
	friend istream &input(istream& temp_cin, Person& p);
	friend ostream & print(ostream& temp_cout, const  Person &p);
private:
	string name;
	string address;
public:
	string get_info()const{
		return "name:" + name + "\n address:" + address;
	}
	Person()=default;
	Person(const string &n, const string &address) :name(n), address(address) {};
};

istream &input(istream& temp_cin, Person& p) {
	temp_cin >> p.name >> p.address;
	return temp_cin;
}

ostream & print(ostream& temp_cout,const  Person &p) {
	temp_cout << p.name << "," << p.address << endl;
	return temp_cout;
}

要注意的是,friend修饰的外部函数,仅仅表示i这个函数是友元的,不算是声明,所以需要在类的外部单独的声明。。

练习

7.20
如果某一个外部函数需要调用类的private成员,就需要将该函数声明为这个类的友元函数。

好处在于,对于某些是类的接口,却不是类的成员函数的函数,可以直接访问类的数据成员。

坏处在于,这等于在破坏封装性,友元函数可以直接访问类的private成员,带来了不安全性。

7.21

struct Sales_data
{
	friend istream& input(istream& temp_input, Sales_data& data);
	friend ostream& print(ostream& temp_cout, const Sales_data& data);
	friend Sales_data add(Sales_data &data1, const Sales_data & data2);
private:
	string bookNo;
	unsigned units_sold=0;
	double revenue = 0.0;
public:
	string isbn() const { return bookNo; };
	Sales_data& combine(const Sales_data& );
	double avg_price()const;

	//构造函数
	//1.默认构造函数
	Sales_data() =default;
	//2.仅初始化isbn
	Sales_data(const string& isbn) :bookNo(isbn) {};
	//3.数据成员都初始化
	Sales_data(const string& isbn, unsigned u, double p) :bookNo(isbn), units_sold(u), revenue(u*p) {};
	//4.使用流来初始化
	Sales_data(istream& temp_input) {
		input(temp_input,*this);
	};
};

7.22
上面总结中的代码就是

发布了54 篇原创文章 · 获赞 6 · 访问量 3343

猜你喜欢

转载自blog.csdn.net/zengqi12138/article/details/104128952