Chapter 30.类成员指针、嵌套类、局部类、联合、固有不可移植特征

类成员指针

简介

有时我们可能需要类中成员的指针(static明显不算,这个不是类成员),这就是类成员指针,分为两种,类数据成员指针和类成员函数指针

eg://ClassMemberPointer.h
#ifndef __CLASS_MEMBER_POINTER__
#define __CLASS_MEMBER_POINTER__

#include <string>
#include <cstddef>
class Screen
{
public:
	Screen():cursor(0),height(0),width(0){}
	typedef std::string::size_type index;
	char get() const;
	char get(index ht,index wd) const
	{
		return 'a';
	}
public:
	std::string content;
	index cursor;
	index height;
	index width;
};

#endif	//__CLASS_MEMBER_POINTER__
//main.cpp
#include "ClassMemberPointer.h"
#include <iostream>
using namespace std;
typedef char (Screen::*pFunction)(Screen::index ht,Screen::index wd) const;
void action(Screen *screen,pFunction=&Screen::get);

int main()
{
	//类数据成员指针
	//格式:
	//数据成员类型 类名::*指针名=&类名::数据成员;
	std::string Screen::*pcontent=&Screen::content;
	Screen::index Screen::*pindex;
	pindex=&Screen::width;
	pindex=&Screen::height;
	
	//使用数据成员
	//.* ->* 成员指针解引用/箭头
	Screen s1;
	Screen::index height=s1.*pindex;//解引用 pindex=&Screen::height;
	Screen *s2=new Screen;
	height=s2->*pindex;
	cout<<height;//0

	//类成员函数指针
	//格式:
	//返回值类型 (类名::*函数指针名)([形参表]) const=&类名::成员函数//如果是const的还要有const
	//可以如下调用
	//1.
	//pFunction action=&Screen::get;
	//2.通过typedef来使用函数action
	Screen *screen=new Screen();
	action(screen);
	char ch;
	cin>>ch;
	return 0;
}

void action(Screen *screen,pFunction)
{
	
}

嵌套类

eg:
template <class Type>
class Queue
{
private:
	struct QueueItem;
	QueueItem *head;
	QueueItem *tail;
};
template <class Type>//在外部定义嵌套类模板,在内部就不写了
struct Queue<Type>::QueueItem
{
	QueueItem(const Type &t):item(t),next(0){}
	Type item;
	QueueItem *next;
}

局部类

1.明显只能在内部定义,你在外部定义个我看看。。

2.作用域太小了。。只在局部有作用

3.局部类只能访问外围作用域中定义的类型、static变量、枚举成员

eg:
int a,val;
void foo(int val)
{
	int fooOuter();
	static int si;//这算是外围作用域,可以访问,看第3条
	enum Loc{a=1024,b};//同上
	class Bar
	{
	public:
		friend int fooOuter();//现在外外围作用域可以访问这个局部类的成员了。。
		Loc locVal;//同上,这里使用了枚举类型名
		int barVal;
		void fooBar(Loc l=a)
		{
			barVal=val;//这不算是外围作用域了。。算外外围作用域//error
			barVal=::val;//这使用了全局:://ok,全局
			barVal=si;//ok,static
			locVal=b;//ok,枚举
		}
	};
}

联合

这个虽然在c语言中就知道了。。但在c++中又有了点新东西

1.这是一个节省空间的类,同一时间只有一个数据成员有值,则其他都未定义。。存储内存需要与最大数据成员一样多

2.可以使用private、protected、public访问说明符

3.可以定义构造/析构函数,但不能有虚函数,即不能为基类

4.不能具有静态数据成员、引用成员、定义了构造/析构函数或operator=的类类型成员

eg:
union illegalMembers
{
	Screen s;//has constructor,error
	static int is;//error
	int &rfi;//error
	Screen *ps;//ok,一般指针类型
};
eg:
union TokenValue
{
	char cVal;
	int iVal;
	double dVal;
};
//使用
TokenValue firstToken={'a'};
TokenValue lastToken;
TokenValue *pt=new TokenValue;
lastToken.cVal='z';
pt->iVal=2012;

嵌套联合

在类中经常会看到或者使用

eg:
class Token
{
public:
	enum TokenKind
	{
		INT,
		CHAR,
		DBL;
	};
	TokenKind kind;
	union 
	{
		char cVal;
		int iVal;
		double dVal;
	}val;	
};
Token token;//class object
switch(token.kind)
{
	case Token::CHAR:
		token.val.cVal='A';
		break;
	case Token::INI:
		token.val.iVal=99;
		break;
	case Token::DBL:
		token.val.dVal=3.1415;
		break;
}

匿名联合

eg:
class Token
{
public:
	enum TokenKind
	{
		INT,
		CHAR,
		DBL;
	};
	TokenKind kind;
	union //匿名union不能有private、protected成员,也不能定义成员函数
	{
		char cVal;
		int iVal;
		double dVal;
	};	
};
Token token;//class object
switch(token.kind)
{
	case Token::CHAR:
		token.cVal='A';
		break;
	case Token::INI:
		token.iVal=99;
		break;
	case Token::DBL:
		token.dVal=3.1415;
		break;
}

固有的不可移植的特征

1.位域

算是c语言的东西了。。不过在二进制数据传递给另一程序或硬件设备时还是有用的

2.volatile

与const用法差不多

volatile类型的变量告诉编译器,本变量无需进行代码优化。在多线程的应用中,我们假如读入一个变量到寄存器,此时时间片到期,去处理其他线程了,在重新获得处理机时,volatile类型告诉处理机,重新从变量读取数据到寄存器,而不是用寄存器数据直接处理,这样能够防止脏数据

3.extern "C"

extern "FORTRAN"

extern "Ada"

有一个小要点,extern "C"因为c语言中没有重载函数这一说法,所以在一组重载的函数中只能为一个c函数指定链接指示

eg://如下就出错了,c语言中没有重载
extern "C" void print(const char*);
extern "C" void print(int);

extern "C" 函数的指针

extern "C" void (*pf)(int);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值