Home

Classes and Pointers to Functions

 

A Pointer to Function as a Member Variable

When studying pointers to functions, we learned to use a programmer's type-defined declaration to create an alias to a pointer to function. We used an example such as the following:

typedef double (*Multiply)(const double a);

With this declaration, the word Multiply can be used in place of a function that takes a double-precision value as argument and the function returns a double. We learned that such a Multiply name could be used to declare a variable that in fact would be used as a function. Based on this feature of the C++ language, the Multiply name can also be used to declare a member variable of a class. Such a member variable would be interpreted as a function. The declaration can be done as follows:

typedef double (*Multiply)(const double a);

public value class CSquare
{
public:
    Multiply Perimeter;
};

As done with the regular pointer to function, you don't implement the Perimeter member. In fact, so far, the compiler doesn't know what to do with the word Perimeter. Therefore, you must formally define a function that can implement the behavior that the Perimeter member is supposed to use. Such a function can be defined as follows:

double Perimetre(const double x)
{
    return x * 4;
}

Even with this definition of the Perimetre() function, there is no relationship between the Perimeter member of the CSquare class and the Perimetre() independent function, and the compiler doesn't see any relationship between them. This means that, until you join these two functions, the compiler would not know what to do with the member of the class. To use the Perimeter member of the CSquare class, you should first assign it an appropriate function that has the same signature as its alias. Then you can use the member of the class as if it were a regular method of the class. Here is an example of how this would be done:

using namespace System;

typedef double (*Multiply)(const double a);

public value class CSquare
{
public:
    Multiply Perimeter;
};

double Perimetre(const double x)
{
    return x * 4;
}

int main()
{
    CSquare Sqr;

    double Side = 25.55;
    Sqr.Perimeter = Perimetre;

    Console::WriteLine("Square Characteristics");
    Console::WriteLine("Side:      {0}", Side);
    Console::WriteLine("Perimeter: {0}", Sqr.Perimeter(Side));
    
    return 0;
}

Using this same approach, you can declare different types of pointers to function as you see fit and using the function signature(s) of your choice. Here is an example:

using namespace System;

typedef double (*Multiply)(const double a);
typedef double (*Multiple)(const double x, const double y);

public value class CSquare
{
public:
    Multiply Perimeter;
    Multiple Area;
};

double Perimetre(const double x)
{
    return x * 4;
}

double Surface(const double x, const double y)
{
    return x * y;
}

int main()
{
    CSquare Sqr;

    double Side = 25.55;
    Sqr.Perimeter = Perimetre;
    Sqr.Area = Surface;

    Console::WriteLine("Square Characteristics");
    Console::WriteLine("Side:      {0}", Side);
    Console::WriteLine("Perimeter: {0}", Sqr.Perimeter(Side));
    Console::WriteLine("Area:      {0}", Sqr.Area(Side, Side));
    
    return 0;
}

This would produce:

Square Characteristics
Side:      25.55
Perimeter: 102.2
Area:      652.8025
Press any key to continue . . .

In the class, we use the Multiply word as a type, the same way we would use a normal data type, to declare a variable. Although this looks like that, it follows different rules. While you can declare two variables using the same data type, you cannot declare two pointer to methods using the same type:

public value class CSquare
{
public:
    // This works
    double a, b;
    // This produces an error
    Multiply Perimeter, Area;
};

If you do this, you would receive an error when you compile the application.   

 

Previous Copyright © 2006 FunctionX, Inc. Next