c ++ --- classes and objects (initialization list, friend functions, friend classes, static member, inner classes)

- initialization list
- static members
- friend function
- friend class
- class interior

1. initialization list
in constructor previously learned can not be called to initialize our class, our class can only be called an assignment. Our init only be initialized once, and constructors can make multiple assignments

  • Initialization list syntax
    initialization list: start with a colon, followed by a list of data members to have a good delimited, behind every member variable followed by an initial value or expression in parentheses

    class Cat{
    public:
    Cat(string name,string color):_name(name),_color(color){
    };
    private:
    string _name;
    string _color;
    };

note:

  • Every member variables initialization list can appear only once (that is, we initialization can be initialized only once)
  • Class includes (a reference member variables, const member variables, class type members (none of the class default constructor)) when we have to put the initialization list and retrograde initialization.
#include <iostream>
#include <string>
using namespace std;
class Cat{
public:
	Cat(string name,string color,int age,string kind) :_name(name),_color(color)
			,_kind(kind),_age(age){	
	}
private:
	string _name;
	int &_age;
	const string _kind;
	string _color;
};

This time is not being given when the assignment in the constructor will throw an error
Here Insert Picture Description
and the error is a member of unreferenced variables
Here Insert Picture Description
must be initialized in the initialization of our list for a custom class does not have a default constructor

#include <iostream>
#include <string>
using namespace std;
class A{
public:
	A(int a){};

};
class Cat{
public:
	Cat(string name,string color,int age,string kind,A a) :_name(name),_color(color)
			,_kind(kind),_age(age),_a(a){	
	}
private:
	string _name;
	int &_age;
	const string _kind;
	string _color;
	A _a;
};

If not, it would form the following circumstances
Here Insert Picture Description

  • Try to use initialization list to initialize, because regardless of whether you use the initialization list, for custom type member variables will be initialized using the initialization list.
  • 成员变量在类中声明的次序就是其在初始化列表中初始化的顺序,与我们初始化列表变量的顺序是没有关系的。
class Array{
public:
	Array(int a,int b):_b(b++),_a(a+_b){
	};
private:
	int _a;
	int _b;
};

这时候结果是_a是一个随机数,因为_a比_b先初始化,这时候我们_b是一个随机数,在_a初始化完毕之后才会吃实话_b,所以我们的_b是一个b++的数

explicit关键字
构造函数不仅仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换的作用,比如先前我们实现的日期类

class Date { 
public:     
	Date(int year) :_year(year){
	}
private:   
		int _year;    
		int _month;
		int _day;
};

void TestDate() {
	Date d1(2018);    // 用一个整形变量给日期类型对象赋值    
	// 实际编译器背后会用2019构造一个无名对象,最后用无名对象给d1对象进行赋值   
	d1 = 2019; 
}

上面赋值是可以的,但是这样让我们的代码并不是那么容易理解,此时explicit关键字就是构造函数,将会禁止单参数构造函数的隐式转换

explicit Date(int year):_year(year){
}

2. static成员
声明为static的类成员称为我们的类的静态成员,用static修饰的成员变量称为静态成员变量,用static修饰的成员函数,称之为静态成员函数。
静态成员变量一定要在类外进行初始化
在c语言我们就知道static修饰局部变量会改变局部变量的作用域和生命周期,修饰全局变量同样会改变变量的作用域和生命周期,在类中也不列外,同样会改变类中成员的作用域和生命周期。比如我们在一段程序中去计算我们类被创建了多少次

#include <iostream>
#include <string>
using namespace std;
class Cat{
public:
	Cat(){
		sum++;
	}
	static int GetSum(){
		return sum;
	}
private:
	string _name;
	string _color;
	static int sum;
};
int Cat::sum = 0;
int main(){
	Cat* cat = new Cat[100];

	cout << Cat::GetSum() << endl;
	system("pause");
	return EXIT_SUCCESS;
}

只要在我们程序最后打印出我们的sum即可
Here Insert Picture Description

static特性

  • 静态成员是所有类对象所共享,不属于哪一个具体的实例
  • 静态成员变量必须在类外定义,定义时不添加static关键字
  • 类静态成员用类名::静态成员或者对象.静态成员来访问
  • 静态成员函数没有this指针,不能访问任何非静态成员
  • 静态成员和类的普通成员一样,也有public,protected,private访问限定符。
    静态成员函数不能调用非静态成员函数
    非静态成员成员函数可以调用类中静态成员函数

友元
友元又可以分为友元函数和友元类
- 友元函数
友元时我们突破封装的方式,因为在我们进行封装的时候我们在一些类中不能让外界访问,此时我们需要一些特例来处理我们的特殊情况,比如我们在Date类中进行重载我们输出的<<操作符的时候,第一个参数时我们的this指针,这时候是不能够处理这种情况,因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置,this指针默认时第一个参数也就是左操作数了,但是实际使用中cout需要是第一个形参对象,才能正常使用,所以我们要将operator<<重载成全局函数,这样的话我们也会破坏我们的封装性。

class Date {
public:    
	Date(int year, int month, int day) : 
		_year(year), _month(month), _day(day) {
	}        
	ostream& operator<<(ostream& _cout){ 
		_cout << d._year << "-" << d._month << "-" << d._day;
		return _cout; }    
private:    
	int _year;    
	int _month;    
	int _day
};

int main() { 
	Date d(2017, 12, 24);    
	d << cout;    
	return 0; 
}

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但是需要在类中的内部需要声明,在声明的时候需要加上friend关键字
重点

  • 友元函数可以访问类的私有成员,但不是类的成员函数
  • 友元函数不能用const修饰
  • 友元函数不能用const修饰
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用和原理相同、

- 友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员

  • 友元关系是单向的,不具有交换性
  • 友元不能传递
class Date;   // 前置声明
class Time {   
	friend class Date;   
	// 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变 量 
public:   
	Time(int hour, int minute, int second): 
		_hour(hour) , _minute(minute) , _second(second){
	}   
private:   
	int _hour;   
	int _minute;   
	int _second; 
};

class Date {
public:  
	Date(int year = 1900, int month = 1, int day = 1) : 
		  _year(year), _month(month), _day(day){
	}     
	void SetTimeOfDate(int hour, int minute, int second){  
			  // 直接访问时间类私有的成员变量       
	 _t._hour = hour;      
	 _t._minute = minute;     
	 _t.second = second;  
		  };
private:   
	int _year;  
	int _month;  
	int _day;   
	Time _t; 
};
  1. 内部类
    概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。注意此时这个内部类是一个独立的 类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。
    注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中 的所有成员。但是外部类不是内部类的友元。
    特性:
  • 内部类可以定义在外部类的public、protected、private都是可以的。
  • Note that inner class can directly access external class static, enumeration member, the object does not require an external class / class name.
  • sizeof (external type) type = external, and internal class nothing
class A {
private:   
	static int k;   
	int h; 
public:   
	class B {
public:        
	void foo(const A& a){
		cout << k << endl;//OK          
		cout << a.h << endl;//OK      
	}  
}; 
};
 int A::k = 1;
 int main() {
	 A::B b;   
	 b.foo(A());      
	 return 0; 
 }

Guess you like

Origin blog.csdn.net/boke_fengwei/article/details/90582820