C++编程指向成员的指针以及this指针的基本使用指南

指向成员的指针

指向成员的指针的声明是指针声明的特例。使用以下序列来声明它们:

[storage-class-specifiers] [cv-qualifiers] type-specifiers [ms-modifier]

qualified-name ::* [cv-qualifiers] identifier

[= & qualified-name :: member-name];

声明说明符:

  • 可选存储类说明符。
  • 可选 const 和/或 volatile 说明符。
  • 类型说明符:类型的名称。这是要指向的成员的类型,而不是类。

声明符:

  • 可选的 Microsoft 专用修饰符。
  • 包含要指向的成员的类的限定名。
  • :: 运算符。
  • * 运算符。
  • 可选 const 和/或 volatile 说明符。
  • 命名指向成员的指针的标识符。

可选的初始值设定项:

  • = 运算符。
  • & 运算符。
  • 类的限定名。
  • :: 运算符。
  • 适当类型的类的非静态成员的名称。

像往常一样,允许在单个声明中使用多个声明符(以及任何关联的初始值设定项)。

指向类的成员的指针与普通指针不同,因为它有该成员的类型的类型信息和该成员所属的类的类型信息。常规指针只标识内存中的一个对象或只具有其地址。指向类的某个成员的指针标识类的所有实例中的该成员。以下示例声明类、Window 和一些指向成员数据的指针。

// pointers_to_members1.cpp

class Window

{

public:

Window(); // Default constructor.

Window( int x1, int y1, // Constructor specifying

int x2, int y2 ); // window size.

bool SetCaption( const char *szTitle ); // Set window caption.

const char *GetCaption(); // Get window caption.

char *szWinCaption; // Window caption.

};

// Declare a pointer to the data member szWinCaption.

char * Window::* pwCaption = &Window::szWinCaption;

int main()

{

}

在前面的示例中,pwCaption 是一个指针,它指向具有 Windowchar* 类型的类 的任何成员。类型 pwCaption 不是 char * Window::*。下一个代码片段将指针声明为 SetCaption 和 GetCaption 成员函数。

const char * (Window::*pfnwGC)() = &Window::GetCaption;

bool (Window::*pfnwSC)( const char * ) = &Window::SetCaption;

指针 pfnwGC 和 pfnwSC 分别指向 GetCaption 类的 SetCaption 和 Window。以下代码直接使用指向成员 pwCaption 的指针将信息复制到窗口标题:

Window wMainWindow;

Window *pwChildWindow = new Window;

char *szUntitled = "Untitled - ";

int cUntitledLen = strlen( szUntitled );

strcpy_s( wMainWindow.*pwCaption, cUntitledLen, szUntitled );

(wMainWindow.*pwCaption)[cUntitledLen - 1] = '1'; //same as

//wMainWindow.SzWinCaption [cUntitledLen - 1] = '1';

strcpy_s( pwChildWindow->*pwCaption, cUntitledLen, szUntitled );

(pwChildWindow->*pwCaption)[cUntitledLen - 1] = '2'; //same as //pwChildWindow->szWinCaption[cUntitledLen - 1] = '2';

.* 和 –>* 运算符(指向成员的指针运算符)的区别在于 .* 运算符选择成员给定的对象或对象引用,而 –>* 运算符通过指针选择成员。(有关这些运算符的更多信息,请参阅使用指向成员的指针运算符的表达式。)

指向成员的指针运算符的结果是成员的类型 - 本例中为 char *。

以下代码片段使用指向成员的指针调用成员函数 GetCaption 和 SetCaption:

// Allocate a buffer.

enum {

sizeOfBuffer = 100

};

char szCaptionBase[sizeOfBuffer];

// Copy the main window caption into the buffer

// and append " [View 1]".

strcpy_s( szCaptionBase, sizeOfBuffer, (wMainWindow.*pfnwGC)() );

strcat_s( szCaptionBase, sizeOfBuffer, " [View 1]" );

// Set the child window's caption.

(pwChildWindow->*pfnwSC)( szCaptionBase );

针对指向成员的指针的限制

静态成员的地址不是指向成员的指针。它是指向静态成员的一个实例的常规指针。由于给定类的所有对象只存在一个静态成员实例,因此可以使用普通的 address-of (&) 和取消引用 (*) 运算符。

指向成员和虚函数的指针

通过指向成员函数的指针调用虚函数就如同直接调用函数一样;将在 v 表中查找并调用正确的函数。

一直以来,虚函数工作的关键是通过指向基类的指针来调用它们。(有关虚函数的详细信息,请参阅虚函数。)

以下代码演示如何通过指向成员函数的指针调用虚函数:

// virtual_functions.cpp

// compile with: /EHsc

#include <iostream>

using namespace std;

class Base

{

public:

virtual void Print();

};

void (Base ::* bfnPrint)() = &Base :: Print;

void Base :: Print()

{

cout << "Print function for class Base\n";

}

class Derived : public Base

{

public:

void Print(); // Print is still a virtual function.

};

void Derived :: Print()

{

cout << "Print function for class Derived\n";

}

int main()

{

Base *bPtr;

Base bObject;

Derived dObject;

bPtr = &bObject; // Set pointer to address of bObject.

(bPtr->*bfnPrint)();

bPtr = &dObject; // Set pointer to address of dObject.

(bPtr->*bfnPrint)();

}

//Output: Print function for class Base

Print function for class Derived

this 指针

this 指针是只能在 class、struct或 union 类型的非静态成员函数中访问的指针。它指向为其调用成员函数的对象。静态成员函数没有 this 指针。

语法

this

this->member-identifier

备注

对象的 this 指针不是对象的一部分;它没有在对象上的 sizeof 语句的结果中反映。相反,当对某个对象调用非静态成员函数时,该对象的地址将由编译器作为隐藏的参数传递给函数。例如,以下函数调用:

myDate.setMonth( 3 );

可以按以下方式解释:

setMonth( &myDate, 3 );

对象的地址可从成员函数的内部作为 this 指针提供。 this 的大多数使用都是隐式的。在引用类的成员时显式使用 this 是合法的,但没有必要。例如:

void Date::setMonth( int mn )

{

month = mn; // These three statements

this->month = mn; // are equivalent

(*this).month = mn;

}

表达式 *this 通常用于从成员函数返回当前对象:

return *this;

this 指针还用于防止自引用:

if (&Object != this) {

// do not execute in cases of self-reference

注意

由于 this 指针无法更改,因此不允许对 this 赋值。C++ 的早期实现允许对 this 赋值。

this 指针有时可直接使用 - 例如,当操作自引用数据结构,而其中需要当前对象的地址时。

// this_pointer.cpp

// compile with: /EHsc

#include <iostream>

#include <string.h>

using namespace std;

class Buf

{

public:

Buf( char* szBuffer, size_t sizeOfBuffer );

Buf& operator=( const Buf & );

void Display() { cout << buffer << endl; }

private:

char* buffer;

size_t sizeOfBuffer;

};

Buf::Buf( char* szBuffer, size_t sizeOfBuffer )

{

sizeOfBuffer++; // account for a NULL terminator

buffer = new char[ sizeOfBuffer ];

if (buffer)

{

strcpy_s( buffer, sizeOfBuffer, szBuffer );

sizeOfBuffer = sizeOfBuffer;

}

}

Buf& Buf::operator=( const Buf &otherbuf )

{

if( &otherbuf != this )

{

if (buffer)

delete [] buffer;

sizeOfBuffer = strlen( otherbuf.buffer ) + 1;

buffer = new char[sizeOfBuffer];

strcpy_s( buffer, sizeOfBuffer, otherbuf.buffer );

}

return *this;

}

int main()

{

Buf myBuf( "my buffer", 10 );

Buf yourBuf( "your buffer", 12 );

// Display 'my buffer'

myBuf.Display();

// assignment opperator

myBuf = yourBuf;

// Display 'your buffer'

myBuf.Display();

}

输出:

my buffer

your buffer

this 指针的类型

通过 const 和 关键字,可以在函数声明中修改 volatilethis 指针的类型。若要将函数声明为具有一个或多个关键字的特性,请将关键字添加到函数参数列表的后面。

请看以下示例:

// type_of_this_pointer1.cpp

class Point

{

unsigned X() const;

};

int main()

{

}

上面的代码声明一个成员函数 X,其中,this 指针被视为指向 const 对象的 const 指针。可以使用 cv-mod-list 选项的组合,但它们始终通过 this 修改指向的对象,而不是 this 指针本身。因此,以下声明将声明函数 X;this 指针是指向 const 对象的 const 指针:

// type_of_this_pointer2.cpp

class Point

{

unsigned X() const;

};

int main()

{

}

成员函数中 this 指针的类型由以下语法描述,其中,cv-qualifier-list 是从成员函数声明符中确定的,可以是 const 和/或 volatile,而 class-type 是类的名称:

[cv-qualifier-list] class-type * const this

换言之,this 始终是 const 指针;无法重新指派它。成员函数声明中使用的 const 或 volatile 限定符适用于由该函数范围中的 this 指向的类实例。

下表介绍了有关这些修饰符的工作方式的更多信息。

this 修饰符的语义

修饰符
含义
const不能更改数据成员;无法调用不是 const 的成员函数。
volatile每次访问成员数据时,都会从内存中加载该数据;禁用某些优化。


将 const 对象传递给不是 const 的成员函数是错误的。同样,将 volatile 对象传递给不是 volatile 的成员函数也是错误的。

声明为 const 的成员函数不能更改数据成员 - 在此类函数中,this 指针是指向 const 对象的指针。

注意

构造函数和析构函数不能声明为 const 或 volatile。但是,可以在 const 或 volatile 对象上调用它们。

以上是 C++编程指向成员的指针以及this指针的基本使用指南 的全部内容, 来源链接: utcz.com/z/337553.html

回到顶部