《C++ Primer》学习笔记(24)类

来源:本站
导读:目前正在解读《《C++ Primer》学习笔记(24)类》的相关信息,《《C++ Primer》学习笔记(24)类》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《《C++ Primer》学习笔记(24)类》的详细说明。
简介:本文章是关于C++课程里类的一些笔记

7.4 Class Scope

----------------------------------------------------------------

void Window_mgr::clear(ScreenIndex i)

{

Screen &s = screens[i];

s.contents = string(s.height * s.width, ' ');

}

此函数中的Window_mgr,说明这个函数都在它的scope里。

如果函数的返回值要使用Window_mgr中的类型的话,必须加上Window_mgr的specify。

比如:

Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen &s);

编译器只有在找到所以类的成员声明之后,才会去处理成员函数的定义。

编译器会现在class里面找,然后在enclosing scope里找,再找不到就会报错。

在类的内部和外部,变量可以重名,但是typedef的定义不能够重名,否则就会报错。

编译器如何处理成员函数内部的名称?

• 在成员函数内部寻找,且仅仅在使用这个名称之前的代码。

• 在类里面找。

• 在这个类前面的scope中找。

如果我们想使用类成员的名称,而不是成员函数里的本地名称,可以通过this或者类名访问:

this->height;

Screen::height;

如果我们想使用类外面的全局名称,就使用"::"这个符号,它意味着全局名称:

::height

7.5 Constructors Revisited

----------------------------------------------------------------

如果在定义一个变量时,是先定义再赋值,那么这个变量会先被赋为默认值,

因此不如在初始化的时候顺便把值给初始化了:

string foo = "Hello World!";

构造函数也是如此,与其在内部赋值,不如在它的参数列表里面指定其成员的初始值。

const类型的变量/引用/指针,以及没有默认构造函数的类,必须在参数列表里被初始化。

在构造函数的参数列表里,成员初始化的顺便并不是列表的顺序,而是它们在类中的存储顺序。

因此,最好按照类中的存储顺序来初始化成员变量,并且不要使用成员变量来初始化另一个成员变量。

Sales_data(std::string s = ""): bookNo(s) { }

Sales_data(std::string s, unsigned cnt, double rev):

bookNo(s), units_sold(cnt), revenue(rev*cnt) { }

Sales_data(std::istream &is) { read(is, *this); }

第一个函数是默认的构造函数,因为它提供的参数列表和默认的参数列表并没有区别。

我们也可以使用空列表来调用它。

----------------

Delegating Constructors

使用其他构造函数来形成自己的构造函数:

Sales_data(std::string s, unsigned cnt, double price):

bookNo(s), units_sold(cnt), revenue(cnt*price) {}

Sales_data(): Sales_data("", 0, 0) {}

Sales_data(std::string s): Sales_data(s, 0,0) {}

Sales_data(std::istream &is): Sales_data() {read(is, *this);}

此时,被delegating的构造函数的参数列表及函数体都会被执行,它们执行完了之后,

delegating函数的函数体会接着执行。

----------------

The Role of the Default Constructor

什么时候会用到默认的构造函数?

• 在block scope中定义nonstatic变量,且没有初始化它。

• 类包含有synthesize default constructor的成员类。

• 当构造函数没有显式的初始化每一个成员变量时。

• 当没有提供完整的数组初始化个数时。

• 当定义一个本地的static对象且没有初始化时。

• 当初始化类似vector的变量时,T()使用了类作为其成员。

----------------

Implicit Class-Type Conversions

不仅仅是build-in类型可以进行转换,class类型也可以。

单参数的构造函数,就代表了一个类型转换,因此这类函数也称为converting constructors。

但要注意的是,转换函数只能接受一次转换,如果构造函数接收string作为参数,那就不能使用:

combine("9-999-99999");

如果在构造函数前加上explicit关键字,意味着我们不能使用它来行类型的隐式转换。

explicit只需要用在单参数的converting constructors上;

explicit只能用在类的内部,不能在类的外部使用;

explicit只能用在直接的initialization上:

Sales_data item1(null_book); // OK

Sales_data item1 = null_book; // ERROR

----------------

Aggregate Classes

我们可以直接访问它的成员:

struct Data {

int ival;

string s;

};

Data val1 = {0, "Anna"};

这种直接访问类成员的方式看其来很简单,实际上有很多缺点:

• 所有的成员变量必须是public。

• 类的使用者必须负责进行冗长且乏味的赋值操作。

• 一旦类修改,所有的赋值操作都要修改。

----------------

Literal Classes

一个aggregate class,如果它的成员变量都是literal类型的,就可以称它literal class。

一个非aggregate class,满足如下要求的也是literal class:

• 所有的成员都是literal类型;

• 至少有一个constexpr构造函数;

• in-class的初始化必须是constant表达式,或者成员类有constexpr构造函数;

• 必须使用默认的析构函数。

7.6 Class Members

----------------------------------------------------------------

static关键字,使得类的成员不再属于某个单独的类对象,而是属于整个类。

被static修饰的成员,可以是const/引用/数组/clas或其他。

被static修饰的成员,可以是private或者public。

class Account {

public:

void calculate() { amount += amount * interestRate; }

static double rate() { return interestRate; }

static void rate(double);

private:

std::string owner;

double amount;

static double interestRate;

static double initRate();

};

每个Account个体仅仅包含owner和amount两个成员,其他被static修饰的都是共用的。

被static修饰的函数,不会有this指针。

被static修饰的函数,也不会是const的。

我们可以通过类的类型名直接访问static变量或函数:

double r;

r = Accout::rate();

当然我们仍然可以通过具体的对象来访问它们。

成员函数可以直接访问被static修饰的成员变量。

在类的外部定义static函数时,不需要使用static修饰,在类的内部做就可以了。

类的构造函数不会去处理static成员变量,同理我们不能在类的内部去处理static变量。

static变量必须在类的外部进行定义和处理,就像是全局变量一样。

为了保证static成员变量只被定义一次,我们通常将它们放置在对应的源文件中。

一般来说,static成员变量不能在类的内部进行初始化,但也有例外的情况:

如果static成员是const integral类型,就可以在内部进行。

如果static成员只用在了编译器可直接使用它的值的地方,就无需在外面再定义,否则就需要。

如果static成员进行了类内部的初始化,外部的定义就不能再赋值了。

static成员定义在了类外面,因此它的数据类型可以是这个类本身。

static成员可以作为构造函数的参数。

提醒:《《C++ Primer》学习笔记(24)类》最后刷新时间 2024-03-14 00:58:05,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《《C++ Primer》学习笔记(24)类》该内容的真实性请自行鉴别。