C++ primer 笔记 7

本文详细介绍了C++类的高级特性,包括别名定义、成员函数的inline属性、mutable成员、返回*this的成员函数、类类型、友元、作用域规则、构造函数的初始化列表、委托构造函数、默认构造函数、聚合类和静态成员等知识点,旨在深入理解C++类的复杂性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

7.3  Additional Class Features


7.3.1  Class Members Revisited


1.除了可以在类中定义成员以外,还可以自定义某种类型的别名

(1)可以定义在public或者private中

(2)可以用typedef或者using

(3)必须在使用别名前就定义好别名

2.成员函数会自动被设置为inline,我们也可以自己显式设置

3.设置为mutable成员即使在const对象中,也可被更改



7.3.2  Functions That Return *this


1.成员函数返回自身的引用的话,即通过*this,返回的是对象自己本身

2.成员函数也可以被重载且特点差不多

3.const成员函数如果返回自身引用时,必须说明该引用是a reference to const

*可以根据是否为const成员函数进行重载


class Screen{
public:
	Screen &display(std::ostream &os){do_display(os);return *this;}
	const Screen &display(std::ostream &os) const {do_display(os);return *this;}
private:
	void do_display(std::ostream &os) const {os<<contents;}
};

分析:

(1)当no-const函数调用do_display函数时,会将this先转换成a pointer to const,再隐式的传给do_display

(2)const成员函数如果要返回对象本身,返回值类型必须是a reference to const

(3)do_display会隐式的定义为inline,所以既不用重复写代码,还不会浪费花销



7.3.3  Class Types


1.即使两个类定义的所有内容相同,它们仍是不同的类

2.forward declaration:先单独declare某个类而不define它

   incomplete type:上面所述的类

   限制:只能define pointer或者reference to incomplete type,还有declare(not define) functions that use incomplete type as parameter or return type

   即不能实际使用他们



7.3.4  Friendship Revisited


1.在一个类中,不仅可以将外部函数declare为friend,还可以将其他类也declare为friend,这些类中的成员函数可以访问最初这个类中的所有member

2.可以只定义其他类中的某个函数为friend,只要用其他类::函数名就好了

3.就算在类中declare某个外部函数是friend后,也要在类外再次declare这个外部函数,否则不能使用



7.4  Class Scope



1.每个类都有自己的作用域,如果想访问类的成员、函数必须通过member access operator(dot or arrow),如果想访问type member必须用scope operator

2.所以在类外define成员函数时,必须提供类名才行,一当看到类名,define其余部分都在这个类的scope内


void Window_mgr::clear(ScreenIndex i){
	Screen &s=screens[i];
	s.contents=string(s.height*s.width,' ');
}
分析:

(1)clear需要用scope operator

(2)Window_mgr的成员数据ScreenIndex还有后面的那些并没有需要用scope operator

(3)如果有返回参数也是类中的话,那么就轮到返回类型需要scope operator了,但此时函数名就不用再加scope operator了,当然也是可以加的



7.4.1  name lookup and class scope

1.name lookup:the process of finding which declarations match the use of a name

rule:①在名字出现前的块中寻找声明语句

②如果没有找到则在外层作用域寻找

③如果还没有找到,则程序报错


2.the rule of class definition

rule:①先compile所有declaration

②再compile function body

*member function definitions are processed after the compiler processes all of the declarations in the class

应用和分析看书284页


3.虽然内层作用域可以重新typedef外层作用域名字,但是类中如果成员已经使用了外层作用域某个typedef的type,则不可以重新用这个外层作用域的type的名字

*所以一般类中的typedef要放在最前面,防止与外层作用域的发生冲突


4.如果想要的是外层作用域的名字,可以用显式使用::

vodi Screen::dummy_fcn(pos heigth){
	cursor=width*::height;    //global one
}


7.5  Constructors Revisited


7.5.1  Constructor Initializer List


1.必须要用initializer list的时候:当成员是const或者是reference或者一个没有default constructor类的对象时

class ConstRef{
public:
	ConstRef(int ii);
private:
	int i;
	const int ci;
	int &ri;
}


//error,it is initialized and then assigned,but it can't initialized correctly 
ConstRef::ConstRef(int ii){
	i=ii;
	ci=ii;
	ri=i;
}

//correct
ConstRef::ConstRef(int ii)::i(ii),ci(ii),ri(i){}

2.成员初始化的顺序按他们在定义中出现的顺序进行,一般来说不会影响什么,但是如果一个成员的初始化是利用另外一个成员的话,就需要注意

class X{
	//i is in front of j
	int i;
	int j;
public:
	//undefined:i is initialized before j
	x(int val):j(val),i(j){}
}


3.当给一个构造方法所有参数提供default arguments,相当于提供了一个default constructor


7.5.2  Delegating constructor


1.委托构造函数把自己的职责委托给其他构造函数,先执行受委托的构造函数的初始值列表,再执行它的函数体,最后在执行委托构造函数的的函数体


7.5.3  default constructor


1.当对象被默认初始化或者值初始化时自动执行default constructor

(1)默认初始化:

①define nonstatic variables or arrays at block scope without initializers

②执行合成默认构造函数时,类中有类的类型的成员

③当类的类型的成员没有在Initializer list中显式初始化时

(2)值初始化:

①数组初始化时没有提供所有的元素

②当我们不使用初始值定义一个局部静态变量时

③当我们通过T()的表达式显式地请求值初始化时


7.5.4  类的隐式转换


1.converting constructor:一个参数的构造函数相当于从那个参数类型转换到该类的类型

2.只允许一步的类的类型转换:编译器只会自动地执行一步类型转换

3.如果将构造函数设置为explicit的话,就能抑制类的隐式转换(只能在类中设置为explicit)

4.当我们使用copy form of initialization时,会进行implicit conversion,所以不能用explicit constructor to initialize

5.即使设置为explicit,我们也可以用构造函数进行强制转换

*标准库中参数是const char *的string构造函数不是explicit的,参数是一个容量的vector构造函数是explicit的


7.5.5  Aggregate Classes


1.特点:①all of its data members are public   ②not define any constructors  ③no in-class initializers  ④has no base class or virtual functions

2.作用:可以通过以下方式初始化

 struct Data{
	int ival;
	string s;
}
Data val={0,"Anna"};
//order of argument must appear in declaration order of the data members


7.5.6  Literal Classes


1.literal classes are literal type


7.6  static Class Members


1.the static members of a class exist outside any object

2.access static member:①directly through the scope operator  ②use an object to access  ③member functions can use static members directly ,without the scope operator

3.static keyword only appear with the declaration inside the class body,but we can define static member function inside or outside of the class body

4.we must define static member data outside the class body,like the member function defined outside the class body with class name::

5.But we can define static const member data inside the class body with in-class initializer.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值