c++primer第七章(类)【7.4】

在类的作用域外访问类内普通数据成员和成员函数只能通过对象、引用、或者指针使用成员访问运算符("."和"->")

Q:在类外部定义成员函数为什么要提供类名和函数名?

A:一个类是一个作用域,在类的外部成员的名字呗隐藏了起来。一旦遇到类名,定义的剩余部分就在类的作用域之内了,剩余部分包括(参数列表,函数体)。

例子:

void Window_mgr::clear(ScreenIndex i) {
	Screen& s = screens[i];
	s.contents = string(s.height * s.width, ' ');
};

编译器在处理参数列表之前,就已经知道我们正处于Window_mgr类之中了。

  • 当返回类型属于类内成员时候,必须指明是哪个类定义了的它。
Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen& s) {
	screens.push_back(s);
	return screens.size() - 1;
}

7.4.1名字查找与类的作用域

名字查找:寻找与所用名字最匹配的声明的过程

  1. 在名字所在的块中寻找声明语句,只考虑在这个名字使用之前的声明
  2. 没找到的话,就继续查找外层作用域
  3. 如果没有找到匹配的声明,则程序报错。

定义在类内部的成员函数来说,解析名字的方式和上述不同。

类的定义分两步:(这种两阶段的处理方式只适用于成员函数中使用的名字)

  • 首先,编译成员的声明
  • 知道类全部可见后才编译函数体。

NOTE:编译器处理完类中全部声明才会处理成员函数的定义,所以和函数的声明顺序无关。

例子:

typedef double Money;
string bal;
class account {
public:
	Money balance() { return ball; }
private:
	Money ball;
};

几点需要注意:

  1. 类中先去编译所有的声明,此时发现没有Money数据类型,就到类外查找。发现了Money就是double类型
  2. balance函数题在整个类可见后处理,所以此时return的数据类型(ball)是类内的Money类型而不是string类型。

类型名需要特殊处理

一般的,内层作用域可以重新定义外层作用域中的名字。但是,类是很特别的,不允许在类中重新定义外层作用域的某个名字。

typedef double Money;
string bal;
class account {
public:
	Money balance() { return ball; }
private:
	Money ball;
	typedef double Money; //错误,不能重新定义!但是vs没报错!有些编译器可以顺利的通过这样的代码。
	//实际上是一种错误行为!
};

成员定义中的普通快作用域的名字查找

成员函数名字查找的顺序:

  1. 函数体内
  2. 类内
  3. 类外

汗。。。这书写的太尼玛的复杂了!

不就是说明:

在类中,函数参数列表当中的变量不要和类中定义的变量采用“相同的名字”,否则会混淆吗?

万一要是用了怎么办呢?

  1. 如果在类中定义了一个height,参数列表也有一个height,想用类中那个
    void Screen::dummy_fcn(pos height){
        cursor = width * this->height;
        //或者
        //cursor = width * Screem::height;
    }
  2. 如果想用全局变量中的那个。
    void Screen::dummy_fcn(pos height){ 
        cursor = width * ::height;
     }
  3. 当成员定义在类的外部,不仅仅考虑在类定义之前的全局变量,即使是在成员函数定义之前的都可以使用
    int height;
    class Screen {
    public:
    	typedef string::size_type pos;
    	void setHeight(pos);
    	pos height = 0; //隐藏了外层的height
    };
    
    Screen::pos verify(Screen::pos );
    void Screen::setHeight(pos var) {
    	height = verify(var);
    }
    

猜你喜欢

转载自blog.csdn.net/qq_34269988/article/details/86574459