C++浓缩(六)

10.4 this指针

目前,每个类成员函数都只涉及一个对象,即调用它的对象;但有时候方法可能涉及到两个对象,这种情况下需要使用this指针。

定义一个成员函数,查看两个Stock对象,并返回股价较高的那个对象的引用。

  • 若希望该方法对两个对象进行比较,必须将第二个参数作为参数传递给它。

  • 出于效率,可按引用来传递参数。

  • 如何将方法的结果传回给调用程序呢?最直接的方法让方法返回一个引用,该引用指向股价总值较高的对象。

cosnt Stock & topval(const Stock & s) const;

该函数隐式访问一个对象,而显式地访问另一个对象,并返回其中一个对象的引用。

括号中的const表明,该函数不会修改被显式地访问的对象;而括号后的const表明,该函数不会修改被隐式地访问的对象。

由于该函数返回了两个const对象之一的引用,因此返回类型也应为const引用。

实际上,如果可以使用>来比较这两个对象,将更为清晰。可以使用运算符重载(11章)完成这项工作。

注意:topval()将引发一个小问题。

const Stock & Stock::topval(const Stock & s) const
{
     if(s.total_val > total_val)
          return s;
     else
          return ???;
}

其中,s.total_val是作为参数传递的对象的总值,total_val是用来调用该方法的对象的总值。

若s.total_val 大于 total_val,则函数将返回指向s的引用;

否则,将返回用来调用该方法的对象,问题在于,如何称呼这个对象?

使用this指针,this指针用来调用成员函数的对象。

一般来说,所有的类方法都将this指针设置为调用它的对象的指针。

缺失,topval()的total_val是this->total_val的简写(使用->运算符,通过指针来访问结构成员。这也适用于类成员)。

注意:

如果方法需要引用整个调用对象,则可以使用表达式*this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。

然而,要返回的并不是this,因为this是对象的地址,而是对象本身,即*this。

现在,可以将*this作为调用对象的别名来完成前面的方法定义。

const Stock & Stock::topval(const Stock & s) const
{
    if(s.total_val > total_val)
        return s;
    else
        return *this;
}

返回类型为引用意味着返回的是调用对象本身,而不是其副本。

当然,我们想知道this指针是否有用。显然,应在一个包含对象数组的程序中使用这种新方法。因此,接下来介绍对象数组。

10.5 对象数组

声明对象数组的方法与声明标准类型数组相同:

Stock mystuff[4];

当程序创建未被显式初始化的对象时,总是调用默认构造函数。

上述声明要求,

  • 要么没有显式定义任何构造函数;

  • 要么定义了一个显式默认构造函数;

const int STKS = 10;
Stock stocks[STKS] = {
     Stock("aaa", 12.5, 20),
     Stock(),
     Stock("bbb", 130, 3.25),
}

初始化对象数组的方案是:首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。因此,要创建类对象数组,则这个类必须有默认构造函数。

如下:通过使用sotck指针来跟踪对象数组中值最高的元素。

#include<iostream>
#include "stock10.h"
const int STKS = 4;
int main()
{
	Stock stocks[STKS] = {
		Stock("aa", 12, 20),
		Stock("bb", 200, 2.0),
		Stock("cc", 60, 0.5),
		Stock("dd", 120, 20.0)
	};
	for (int i = 0; i < STKS; i++) 
	{
		stocks[i].show();
	}
	const Stock * top = &stocks[0];
	for (int i = 0; i < STKS; i++) 
	{
		top->topval(stocks[i + 1]);
	}
	top->show();
	
	return 0;
}

10.6 类作用域

  • 在类中定义的名称(如类数据成员名和类成员函数名)的作用域为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。

  • 公有成员函数也是如此,因此要调用公有成员函数,必须通过对象。

  • 同样,在定义成员函数时,也须使用域解析运算符。

下面代码演示了如何访问具有类作用域的标识符。

#include <iostream>
class Ik
{
    private:
        int fuss;
    public:
        Ik(int f = 9) {
            fuss = f;
        }
        void ViewIk() const;
};
void Ik::ViewIk() const {
    using namespace std;
    cout << fuss << endl;
}
int main()
{
    Ik * pik = new Ik;
    Ik ee = Ik(0);
    pik->ViewIk();
    ee.ViewIk();
    return 0;
}

10.6.1 作用域为类的常量

。。。。。。。。。。。

10.6.2 作用域内枚举

。。。。。。。。

10.7 抽象数据类型

Stock类非常具体,然而,常通过定义类是表示更通用的概念。例如,就抽象数据类型ADT而言,实用类是一种非常好的方式。

如:C++使用栈来管理自动变量。

首先,栈存储了多个数据项;

其次,栈可执行的操作;

  • 创建空栈;

  • 将数据项添加到堆顶;

  • 从栈顶删除数据项;

  • 查看栈是否填满;

  • 查看栈是否为空;

将上述描述转换为一个类声明,公有成员函数提供了栈操作的接口,私有数据成员负责存储栈数据。

私有部分表示数据存储的方式,可使用常规数组、动态分配数组或更高级的数据结构(如链表)。

程序如下:

stack.h
#ifndef STACK_H_
#define STACK_H_
typedef unsigned long Item;
class Stack
{
     private:
          enum{MAX=10};
          Item items[MAX];
          int top;
     public:
          Stack();
          bool isempty() const;
          bool isfull() const;
          bool push(const Item & item);
          bool pop(Item & item);
}
#endif
=================
stack.cpp
#include<iostream>
#include "stack.h"

Stack::Stack() {
	top = 0;
}

bool Stack::isempty() const{
	return top == 0;
}

bool Stack::isfull() const{
	return top == MAX;
}

bool Stack::push(const Item & item) {
	if(top < MAX) {
		items[top++]=item;
	}else 
		return false;
}

bool Stack::pop(Item & item) {
	if(top <= 0)
	{
		item = items[top--];
		return true;
	}
	else
		return false;
}
=====================
usestack.cpp
#include<iostream>
#include "stack.h"
int main()
{
	
}


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