C++primer读书笔记6-类的细节知识

1:类成员函数的调用
Tclass A;
A.func();
实际上func函数里面有一个默认的形参,参数是A.this。所以表面上时A.func(),实际上是Tclass::func(A.this)。


2:类中的inline函数
<1> 类定义体中直接定义的函数被被默认为inline函数
<2> 类定义体中声明为inline的函数
<3> 类定义体中没有声明,但是在函数定义时加了inline 关键字的函数


3: 类的声明与定义


Class A;//这是声明
Class B //这是定义
{
};


类声明的用处和限制:
<1> 指向该类型的指针或者引用
<2> 用于声明用该类型作为形参或者函数返回类型的
<3> 不能使用不完全的类型来定义变量


4:this 指针
类成员函数内部的隐含形参是this,一般没必要使用this指针来增加冗余, 当需要返回整个对象的引用而不是对象的一个成员时候,就要使用this指针
有时候为了避免混淆,使用this->member
const类型的函数因为不能修改数据成员,所以返回的引用对象也必须是const类型
const& A func() const{ return *this;}


5:基于const的重载
<1>只用形参的类型是const的指针或者引用的时候,const才可以作为重载的因素,否则对于const的形参,编译器将会忽略const。
<2>const 作为后缀修改函数的时候可以作为重载的因素
此时怎么调用选择调用重载函数,当类对象时const类型的时候就调用const类型的函数,当类对象时non-const的时候就调用non-const的函数。当然const的对象也不能调用non-const的成员函数。


6:mutable
数据成员声明为mutable的时候,在const类型的成员函数,或者const对象时候,都可以修改数据成员的值。


7:构造函数


当没有构造函数的的时候,编译器自动合成一个默认的构造函数,当自己提供一个构造函数的时候,编译器就不会再提供默认的合成构造函数


构造函数与其他函数相比不同点:没有返回类型;可以跟一个初始化列表,初始化不同于赋值,赋值是在函数内部进行的,赋值的速度慢于初始化。


当数据成员是引用或者const类型的变量时候,必须在初始化列表中进行初始化


当数据成员是static的时候,成员不能再构造函数中初始化,只能在定义类的头文件中进行诸如:
int A::m_c = 100;的初始化。


8:默认构造函数的必要性
给类提供一个默认构造函数总是必要的。
<1> 没有默认构造函数的,不能开辟动态数组
<2> 没用默认构造函数的,静态数组必须为每一个元素提供一个显式的初始化表达式
<3> 指定类型为无默认构造函数的容器时,就不能只能只指定容器大小。
如:A *p = new A[10]; A arr[10]; vector<A> vec(10); //这三个表达式都需要A的默认构造函数,所以提供一个默认的构造函数,通常是必要的。


A obj;
A obj = A();
经过反汇编分析,这两个表达式汇编代码都是一样的,所以针对第二个式子并不是调用了两次构造函数。


9:隐式类型转换
诸如这样的类
class A
{
public:
   A();
   A(int x):m_a(x){}
   ~A();
private:
   int m_a;
};


A a = 100;//ok
这里没有出错的原因就是发生了隐式的类型转换,会调用构造函数A(int x)将100转换成一个新的临时对象。


如果想阻止这种隐式的诡异的转换就需要在构造函数中添加一个explicit 关键字,只能只能显式的调用构造函数。
explicit A(int x):m_a(x){}


10:友元
友元既可以是类又可以是函数,友元机制允许非成员的类或者函数访问类的成员。
友元的声明和作用域: 类中的友元声明已经将作为友元的类或者函数引入到类的外围作用域中,友元函数还可以在类的内部定义。


友元的规则:必须先定义包含成员函数的类,然后才能将成员函数设为别的类的友元。
#ifndef DDCC_F_H
#define DDCC_F_H
#include<iostream>
using namespace std;
class A;
class B
{
public:
B();
~B();
void disFunc(A& a);
private:
int m_d;

};


class A
{
public:
A();
~A();
friend int func(){return 100;}
friend void B::disFunc(A& a);
void print();
private:
int m_a;
char m_c;
};
#endif


11:static 成员


static数据成员独立于该类的任何对象而存在,static数据成员是与类关联的对象,并不与该类的对象相关联。
static成员函数没有this指针,可以直接访问类的static成员,但是不能访问non-const成员。


<1> static 数据成员的定义:定义只能在类定义体的外部定义,不能通过构造函数初始化。
<2> const static 数据成员:
class A
{
public:
A();
private:
static const int m_d = 100;
};


const int A::m_d;


这种const static的数据成员可以直接在类里面初始化,但是任然必须在类的定义体外进行定义。
<3> static 成员不是类对象组成部分
所以:
class A
{
public:
A();
void func(int x = m_b); //OK
private:
static A m_A;//OK
static const int m_b = 10; 
};
也就是说在类中可以使用static  的类类型作为数据成员,也可以使用static数据成员作为函数的默认参数。这些都是non-static成员不能做到的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值