Essential C++浓缩笔记(四)——基于对象的编程风格

来自Stanley B.Lippman的《Essential C++》第四章重要内容的总结,第四章目录:

Essential C++浓缩笔记(四)——基于对象的编程风格_第1张图片

1、实现Class

Class声明 

只有前置声明之后 才能有类指针的定义 或者 以此Class作为数据类型

calss Stack;                   //声明
...
Stack *pt = 0;                //定义一个类指针
void pocess(const Stack&);    //以Stack作为数据类型

Class定义

所有member function都必须在Class主体内进行声明,至于是否要同时进行定义,可以自由定义。如果定义在Class以外,用": :" 表示xx函数是xx类的一个member

 

2、 构造函数(constructor)和折构函数(destructor)

构造函数是用来初始化 date member的函数,constructor的函数名称必须与Class名称相同,没有返回值,可以被重载。

定义方法一:

class Triangular {
public:
	Triangular();		//default constructors
	Triangular(int len);		
	Triangular(int len, int beg_pos);
};

如果构造函数没有任何参数,有两种可能:

1、它不接受任何参数,有可能有参数但是参数在这个构造函数内已经被写死,不允许更改

2、为每个参数提供了默认值,这种有默认值的构造函数也可以作为default 构造函数

定义方法二:

成员初始化列表,欲赋值给member的数值被放在member名称后面的小括号中。

Trianglular::Triangular(int len, int bp):_name("Triangular")
{
    _length = len > 0 ? len : 1;
    _beg_pos = bp > 0 ? bp : 1;
    _next = _beg_pos - 1;
}

 折构函数 与构造函数相对,一旦某个class提供有destructor,当其object结束生命时,便会自动调用destructor处理善后。主要用来释放在constructor中或者对象生命周期中分配的资源。

 

3、mutable和const

对于const参数,编译器必须保证参数在程序运行过程中不会被修改。

凡是在class主体以外定义的,如果是一个const member function,那就必须同时在声明与定义中指定const。

class Triangular{
public:
    int elem(int pos) const;    //声明
...
};

int elem(int pos) const{
    return _elem[pos-1];        //定义时也要指定const
}

 mutable

如果_next被表示为mutable,那么可以宣称,对_next所做的改变不会破坏class object的常量性。

 

4、this指针

this指针在member function内用来指向其调用者,它可以让我们访问调用者的一切,下面提供copy函数的定义及调用。

Triangular& Triangular::copy(const Triangular &rhs) {
	_length = rhs._length;
	_begin_pos = rhs._begin_pos;	
	return *this;
}


tr1.copy(tr2);                    //调用,将tr2复制给tr1

5、静态类成员

静态成员数 static date member

静态成员数用来表示唯一的、可共享的member。它可以在同一类的所有对象中被访问。static date member在定义的时候它的名称必须附上class scope运算符。

class Triangular{
public:
//...
private:
    static vector_elems;        //static data member声明
};

//以下代码放在程序代码文件中,例如Triangular.cpp
vectorTriangular::_elems;        //绝对不能丢,否则无法被编译器实现

静态成员函数

一般情形下,member function必须通过其类的某个对象来调用,但是对于静态成员函数可以直接调用,前提是利用class scope说明基于的类对象,且静态成员函数没有访问任何的non-static member。

Triangular tri;                        //定义一个Triangular对象,名字是tri
bool is_elem = tri.is_elem(ival);      //调用function member

bool is_elem = Triangular::is_elem(ival); //如果is_elem是静态成员函数,可以直接调用
static bool is_elem(int);                //在class内的函数声明

6、运算符重载

 像定义member function那样来定义运算符,唯一的差别是它不用指定名称,只需要在运算符前加上关键字operator即可。


class Triangular_iterator{
public:
    bool operator==(const Triangular_iterator&) const;    //运算符重载声明
...
};

inline  bool operator==(const Triangular_iterator &rhs) const{
    return _index==rhs._inedx;                            //定义
}

if(trian1 == trian2)...                                    //调用

运算符重载规则:

1、不能引入新的运算符;2、运算符函数列表中,必须至少有一个参数为Class类型;3、优先级不可改变 

 

7、访问类的私有成员

任何类都可以将其他function或class指定friend,friend具备与class member function相同的访问权限,可以访问class 的私有成员。只需要在某个函数的原型上加上关键字friend,就可以将它声明为某个class的friend。

为了让定义成功通过编译,必须在声明之前,提供类的定义(使用的那个类),否则无法确定函数原型是否正确。

也可以把整个类作为另一个类的friend

class Triangular{
    friend class Triangular_iterator;
    ...
};

 如果能通过public member function来访问私有成员,那么就不必通过建立friend 关系。

 

8、function object

function object是一种提供有function call运算符“()”的class

bool operator()(int value) const;        //声明

bool Lessthan::operator()(int value) const //定义
{
	return value < _val;
}

    
for (int i = 0; i < vec.size(); i++)     //调用
{
	if (lt(vec[i]))		
	count++;
}

通常会把function object当作参数传给泛型算法 

vector::const_iterator iter = vec.begin();
vector::const_iterator it_end = vec.end();
os << "elements less than" << lt.comp_val() << endl;
while ((iter = find_if(iter, it_end, lt)) != it_end)	//把function object当作参数传给泛型算法
{
	os << *iter << ' ';
	++iter;
}

 

 

遇到的问题及总结

1、记录程序运行的时间(秒及毫秒)

//程序运行时间(秒)
#include

clock_t startTime, endTime;
startTime = clock();            //计时开始
...
endTime = clock();             //计时结束
cout << "time: " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;

//程序运行时间(毫秒)

#include
DWORD startTime = GetTickCount();//计时开始
....
DWORD endTime = GetTickCount();//计时结束
cout << "The run time is:" << endTime - startTime << "ms" << endl;

2、注释要规范,美观,体现结构

https://blog.csdn.net/weixin_42488570/article/details/80760849

两张注释对比

一)基本没有注释

Essential C++浓缩笔记(四)——基于对象的编程风格_第2张图片

 二)结构清晰,明白易懂

Essential C++浓缩笔记(四)——基于对象的编程风格_第3张图片

 

3、 错误LNK2001无法解析的外部符号

参考这篇文章:https://blog.csdn.net/aaron121211/article/details/50384289

处理函数有可能没有被实现,成员数也有可能没有被实现,比如static vector _elems,除了在class内的申明,还要在cpp文件内定义(实现)!

 

你可能感兴趣的:(C++)