新闻  |   论坛  |   博客  |   在线研讨会
两万字总结《C++ Primer》要点(2)
机器之心 | 2021-04-08 20:05:23    阅读:257   发布文章

第五章 语句

P154-P178

5.1 简单语句

(1)空语句

;    // 空语句

(2)复合语句

复合语句是指用花括号括起来的(可能为空的)语句和声明的序列,复合语句也被称作块(block)。

{}

5.2 语句作用域

定义在控制结构当中的变量只在相应语句的内部可见,一旦语句结束,变量就超出其作用范围。

5.3 条件语句

(1)if 语句

(2)switch 语句

case关键字和它对应的值一起被称为case标签。

case标签必须是整形常量表达式。

如果某个case标签匹配成功,将从该标签开始往后顺序执行所有case分支,除非程序显示的中断了这一过程。

dedault 标签:如果没有任何一个case标签能匹配上switch表达式的值,程序将执行紧跟在default标签后面的语句。

5.4 迭代语句

(1)while 语句

while (condition)
statement

(2)传统 for 语句

for (initializar; condition; expression)
statement

for 语句中定义的对象只在for循环体内可见。

(3)范围 for 语句

for (declaration : expression)
statement

(4)do while 语句

do 
statement
while (condition)

5.5 跳转语句

break

break只能出现在迭代语句或者switch语句内部。仅限于终止离它最近的语句,然后从这些语句之后的第一条语句开始执行。

continue

continue语句终止最近的循环中的当前迭代并立即开始下一次迭代。

goto

goto的作用是从goto语句无条件跳转到同一函数内的另一条语句。

容易造成控制流混乱,应禁止使用。

return

5.6 try语句块和异常处理

C++中异常处理包括:throw表达式、try语句块。

try和catch,将一段可能抛出异常的语句序列括在花括号里构成try语句块。catch子句负责处理代码抛出的异常。

throw表达式语句,终止函数的执行。抛出一个异常,并把控制权转移到能处理该异常的最近的catch字句。

第六章 函数

P182-P225

6.1 函数基础

(1)形参和实参:

实参的类型必须与对应的形参类型匹配。

函数的调用规定实参数量应与形参数量一致。

(2)局部对象

形参和参数体内部定义的变量统称为局部变量,它们对函数而言是"局部"的,仅在函数的作用域内可见,同时局部变量还会隐藏外层作用域中同名的其他变量。

自动对象:只存在于块执行期间的对象。

局部静态对象:在程序的执行路径第一次经过对象定义语句时候进行初始化,并且直到程序终止才会被销毁。

size_t count_calls()
{
static size_t ctr = 0;
return ++ctr;
}

(3)函数声明

函数的三要素:(返回类型、函数名、形参类型)。

函数可被声明多次,但只能被定义一次。

(4)分离式编译

分离式编译允许把程序分割到几个文件中去,每个文件独立编译。

编译->链接

6.2 参数传递

当形参是引用类型,这时它对应的实参被引用传递或者函数被传引用调用。

当实参被拷贝给形参,这样的实参被值传递或者函数被传值调用。

(1)传值参数

(2)被引用传参

(3)const形参和实参

(4)数组形参

为函数传递一个数组时,实际上传递的是指向数组首元素的指针。

void print(const int*);
void pring(const int[]);
void print(const int[10]);
// 以上三个函数等价

数组引用实参:f(int (&arr)[10])

int *matrix[10];   // 10个指针构成的数组
int (*matrix)[10]; // 指向含有10个整数的数组的指针

(5)含有可变形参的数组

initializer_list

for err_msg(initializer_list<string> li)

6.3 返回类型和return语句

2种:无返回值函数和右返回值函数。

return;
return expression;

函数完成后,它所占用的存储空间也会随着被释放掉。

::: warning

返回局部对象的引用是错误的;返回局部对象的指针也是错误的。

:::

6.4 函数重载

重载函数:同一作用域内的几个函数名字相同但形参列表不通,我们称之为重载函数。(overloaded)。

不允许2个函数除了返回类型外其他所有的要素都相同。

重载与作用域

如果在内存作用域中声明名字,它将隐藏外层作用域中声明的同名实体。

6.5 特殊用途语言特性

(1)默认实参

函数调用时,实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参。

typedef string::size_type sz;
string screen(sz ht = 24, sz wid = 80, char background = ' ');

::: tip

当设计含有默认实参的函数时,需要合理设置形参的顺序。一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

:::

(2)内联函数

使用关键词inline来声明内联函数。

内联用于优化规模较小,流程直接,频繁调用的函数。

(3)constexpr函数

constexpr函数是指能用于常量表达式的函数。

6.6 函数匹配

Step1:确定候选函数和可选函数。

Step2:寻找最佳匹配。

6.7 函数指针

函数指针指向的是函数而非对象。

void useBigger (const string &s1, const string &s2, bool pf(const string &, const string &));
等价于
void useBigger (const string &s1, const string &s2, bool (*pf)(const string &, const string &));

第七章 类

P228-P273

类的基本思想是数据抽象和封装。

抽象是一种依赖于接口和实现分离的编程技术。

封装实现了类的接口和实现的分离。

7.1 定义抽象数据类型

(1)this

任何对类成员的直接访问都被看作this的隐式引用。

std::string isbn() const {return bookNo;}

等价于

std::string isbn() const {return this->bookNo;}

(2)在类的外部定义成员函数

类外部定义的成员的名字必须包含它所属的类名。

double Sales_data::avg_price() const {
if (units_sol)
return revenue/units_sols;
else
return 0;
}

(3)构造函数

定义:类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。

构造函数没有返回类型;

构造函数的名字和类名相同。

类通过一个特殊的构造函数来控制默认初始化过程,这个函数叫做默认构造函数。

编译器创建的构造函数被称为合成的默认构造函数。

::: tip

只有当类没有声明任何构造函数的时,编译器才会自动的生成默认构造函数。

一旦我们定义了一些其他的构造函数,除非我们再定义一个默认的构造函数,否则类将没有默认构造函数

:::

7.2 访问控制与封装

(1)访问控制

说明符          用途

public       使用public定义的成员,在整个程序内可被访问,public成员定义类的接口。

private      使用private定义的成员可以被类的成员函数访问,但是不能被使用该类的代码访问,private部分封装了类的实现细节。

(2)友元

类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元。

以friend关键字标识。

友元不是类的成员,不受访问控制级别的约束。

::: tip

友元的声明仅仅制定了访问的权限,而非通常意义的函数声明。必须在友元之外再专门对函数进行一次声明。

:::

// Sales_data.h
class Sales_data {
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::ostream &print(std::ostream&, const Sales_data&);
friend std::istream &read(std::istream&, Sales_data&);
}
// nonmember Sales_data interface functions
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
//Sales_data.cpp
Sales_data 
add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;  // copy data members from lhs into sum
sum.combine(rhs);      // add data members from rhs into sum
return sum;
}
// transactions contain ISBN, number of copies sold, and sales price
istream&
read(istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream&
print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " 
   << item.revenue << " " << item.avg_price();
return os;
}

7.3 类的其他特性

(1)重载成员变量

Screen myScrren;
char ch = myScreen.get();
ch = myScreen.get(0,0);

(2)类数据成员的初始化

类内初始值必须使用=或者{}的初始化形式。

class Window_mgr{
private:
    std::vector<Screen> screens{Screen(24, 80, ' ')};
}

(3)基于const的重载

class Screen {
public:
// display overloaded on whether the object is const or not
    Screen &display(std::ostream &os) 
                  { do_display(os); return *this; }
    const Screen &display(std::ostream &os) const
                  { do_display(os); return *this; }
}

当某个对象调用display的时候,该对象是否是const决定了应该调用display的哪个版本。

(3)类类型

对于一个类来说,在我们创建他的对象之前该类必须被定义过,而不能仅被声明。

(4)友元

友元类

如果一个类指定了友元类,则友元类的成员函数可以访问此类包括非公有成员在内的所有成员。

class Screen {
// Window_mgr的成员可以访问Screen类的私有部分
friend class Window_mgr;
}

令成员函数作为友元

class Screen {
// Window_mgr::clear必须在Screen类之前被声明
friend void Window_mgr::clear(ScreenIndex);
}

7.4 类的作用域

一个类就是一个作用域。

7.5 构造函数再探

(1)构造函数的初始值有时必不可少

::: tip

如果成员是const、引用,或者属于某种未提供默认构造函数的类类型化。我们必须通过构造函数初始值列表为这些成员提供初值。

:::

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

(2)成员初始化的顺序

成员初始化的顺序与它们在类定义中出现 的顺序一致。P259

(3)委托构造函数

使用它所述类的其他构造函数执行它自己的初始化过程。

(4)如果去抑制构造函数定义的隐式转换?

在类内声明构造函数的时候使用explicit关键字。

7.6 类的静态成员

(1)声明静态成员

在成员的声明之前加上关键词static。

类的静态成员存在于任何对象之外,对象中不包含任何与静态成员有关的数据。

(2)使用类的静态成员

double r;
r = Account::rate();

小结

类有两项基本能力:

一是数据数据抽象,即定义数据成员和函数成员的能力;

二是封装,即保护类的成员不被随意访问的能力。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客