C++PrimerPlus 学习笔记 | 第十章 类和对象|4 this 指针 & 5 对象数组 & 6 类作用域

t h i s this this指针

假设我们要创建一个创建汽车比较函数,通过一个类对象调用,给定比的对象,返回价高者的引用,原型如下

const car & higherPrice(const car & c) const;

该函数会隐式的访问的一个对象,就是调用这个函数的类对象,会显式访问一个对象,就是函数形式参数的那一个对象,那么问题来了如何返回这个隐式访问的对象呢?看下面的实例

const car & higherPrice(const car & c) const{
	return price > c.price ? /* ???这边写什么 */ : c;
}

问题在于如何称呼这个被隐式调用的对象,C++给出的解决方法是使用名为 t h i s this this的隐式指针, t h i s this this用于只想调用成员的对象( t h i s this this作为隐藏参数传递给方法)那么上述实例可以改写如下

const car & higherPrice(const car & c) const{
	return price > c.price ? *this : c;
}

一般来说所有类方法都this指针设置为调用他对象的地址,简单来说

// ... car类的某个方法内
price = 1900;
// ==
this->price = 1900;

每一个类或者是结构成员的方法(包含构造函数和析构函数)都有一根this指针,this指针指向调用的对象,如果想要调用整个对象,只需要对this指针解引用即可!在函数括号的添加的const实质上是将this指针限定为const,这样就不能使用this指针修改对象的值,如上所述,所有调用类成员的都是隐式通过this调用的。

对象数组

用户通常使用同一个类多个对象,可以创建独立变量。但是创建对象数组更合适,似乎很高级,其实与创建的一般都数组并无区别

car cars[1000];

当程序常见未被显示初始化的类对象时,总是调用默认构造函数,上述声明要求要么这个类没有显示的声明构造函数,要么定义一个显示的构造函数。

当然你也可以为数组中的每一个元素都显示初始化,如果声明了默认构造函数你可以对所有的元素初始化或者只对一部分元素初始化。

类作用域

C++类引入一种新的作用域叫做类作用域,在类中定义的名称(数据成员名或者是函数成员名)的作用域都为整个类,作用域内整个类的名称都是可知的,在类外是不可知的。也就是说在类作用域不可以直接访问类的对象,公有成员函数也是如此,必须通过对象访问。定义成员函数必须使用作用域解析符

总之在定义类声明或者成员函数定义的时候,可以使用未修饰的成员名称(未限定的),在其它情况下要么使用直接运算符号句号,间接成员运算符->或者作用域解析符.

作用域为类的常量

有时候使得符号常量的作用域为类很有意义,类声明可能用30来制定数组·的长度,该常量对于所有类都相同,因此创建一个所有类的共享的常量似乎很不错,看一下代码

class Cats {
    private:
    const int Len = 10; // 失败
    string catsName[Len];
}

上述的常量声明不可行的,因为声明类只是描述了对象的形式,而不会实际创建对象,在创建对象前将没有用于存储值的空间(C++11提供了成员初始化,但是不用域前面的数组声明),有两种方法可以实现这个目标

第一种方法就是声明枚举,在类声明中声明的枚举作用域为整个类,而因此可以用枚举常量为整形变量提供作用域为整个类的符号名称看如下代码

class Cats {
    enum {CatsCount = 12}
    string catsName[CatsCount];
}

这里的 C a t s C o u n t CatsCount CatsCount只是枚举常量当编译器遇到改名称将用12替换他。

当然C++提供了第二种方法来创建常量就是 s t a t i c static static,如下面所示

class Cats {
    static const int CatsCount = 12;
    string catsName[CatsCount];
}

该变量将与自动变量存储在一起,而不是存储在对象中,因此只有一个CatsCount变量,在C++98中只能使用static声明为枚举或者整数的静态常量,在C++11中消除了这种限制

作用域内枚举(C++11)

传统的枚举可能存在一些问题,可能两个枚举量会存在名称冲突。例如

enum egg {Small,Medium,Large};
enum t_shirt {Small,Medium,Large}

如果上述出现在同一个作用域中,将无法通过编译,他们将发生冲突,为了解决这种冲突C++11提供了一种新的枚举类型,其枚举量的作用域为类,声明如下,在后面追加** c l a s s class class表示类作用域枚举**,也可以使用 s t r u c t struct struct两者没有区别

    enum class egg {Small,Medium,Large};
    enum class T_shirt{Small,Medium,Large};

声明为类作用域枚举后都需要使用枚举名来限定枚举变量,如下

egg e = egg::Small;
T_shirt t_shirt = T_shirt::Large;

这样即使在不同定义定义的枚举量也不会冲突,同时表以也更加清晰了

C++11也提高了作用域内枚举的安全性,在有些情况下,常规枚举自动转换为整形,但是作用域枚举不能隐式的转换为整形

enum normal {Small,Medium,Large};
enum class scoped {Small,Medium,Large};
normal n = Small;
scoped s = scoped::Small;
std::cout << n; // 隐式的转换为整形
//std::cout << s; // 无法隐式的转换为整形,会报错
std::cout << (int)s; // 可以显式的转换为整形

枚举底层用数字表示,在C++98中如何选择取决于实现,对于作用域枚举,C++11取消了这种限制,在默认情况下作用域内枚举类型为int,可以显式的指定类型如下

此处C++PrimerPlus书本提供的语法无法编译,经测试应该是如下语法

// C++PrimerPlus提供的语法,无法通过编译
enum class : short Egg {Small, Medium, Large};
// 能够通过编译的语法
enum class Egg : short Egg {Small, Medium, Large};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值