Lesson 7 | Generic pointer type |
Objective | Generic pointer type as a formal parameter |
void* as Formal Parameter in C++
In C++, a "generic pointer type" refers to a pointer that can point to any data type. The term typically applies to the `void*` type, which serves as a general-purpose pointer. A `void*` pointer does not have a specific data type associated with it, making it "generic."
Key Concepts of a Generic Pointer (`void*`):
-
No Type Information:
- A
void*
pointer is not associated with any specific data type. For example:
void* ptr;
Here, ptr
is a generic pointer that can store the address of any type of data.
-
Used as a Formal Parameter:
-
Type Casting is Required:
-
No Pointer Arithmetic:
- Pointer arithmetic cannot be performed directly on a
void*
because the compiler does not know the size of the underlying data type. If arithmetic is needed, the pointer must first be cast to the appropriate type.
-
Use Cases:
void*
is commonly used in low-level programming where flexibility is needed, such as:
-
Type Safety Concerns:
- Using
void*
sacrifices type safety. The programmer must ensure that the correct type is used when casting. Incorrect type casting can lead to undefined behavior.
Example: `void*` as a Generic Pointer Parameter
Here is a simple example demonstrating the use of a `void*` as a formal parameter:
#include
void display(void* data, char type) {
if (type == 'i') {
std::cout << *static_cast<int*>(data) << std::endl;
} else if (type == 'd') {
std::cout << *static_cast<double*>(data) << std::endl;
} else if (type == 'c') {
std::cout << *static_cast<char*>(data) << std::endl;
}
}
int main() {
int num = 10;
double pi = 3.14;
char letter = 'A';
display(&num, 'i'); // Output: 10
display(&pi, 'd'); // Output: 3.14
display(&letter, 'c'); // Output: A
return 0;
}
Benefits and Drawbacks:
-
Benefits:
- Flexibility: A single function or data structure can handle multiple data types.
- Memory Efficiency: Avoids the need for duplicating code for different data types.
-
Drawbacks:
- Lack of Type Safety: Relies on the programmer to ensure the correct type is used.
- Complexity: Requires explicit type casting, which can lead to errors.
In modern C++, templates and polymorphism are preferred for generic programming as they provide better type safety and flexibility compared to `void*`.
C++ How to Program
Write a function that casts the generic pointer type void* to a standard working type
A key use for the generic pointer type is as a
formal parameter.
For example, the library function
memcpy
is declared in
cstring
as:
void* memcpy(void* s1, void* s2, size_t n);
On older C++ systems and on C systems, memcpy is found in string.h.
The function
memcpy
copies
n
characters from the variable based at
s2
into the variable based at
s1
. It works with any two pointer types as actual arguments. The type
size_t
is defined in
stddef.h
, and is often a synonym for
unsigned int
.
#include <cstring>
void *memcpy(void *to, const void *from, size_t count);
The memmove( ) function copies count characters from the array pointed to by from into the array pointed to by to. If the arrays overlap, the copy will take place correctly, placing the correct contents into the "to" destination,
but leaving the "from" source modified. The memmove( ) function returns a pointer to to. A related function is memcpy( ).
Wide-Character Array Functions
The standard character array-manipulation functions, such as memcpy( ), also have wide-character equivalents. These functions use the header <cwchar>.
Text showcasing a table of functions for handling wide-character arrays (`wchar_t`) in C++ and their equivalent `char`-based functions.
Below is the transcribed information:
Table Analysis:
-
Wide-Character Functions and Their
char
Equivalents
-
wchar_t *wmemchr(const wchar_t *str, wchar_t ch, size_t num)
Equivalent: memchr()
-
int wmemcmp(const wchar_t *str1, const wchar_t *str2, size_t num)
Equivalent: memcmp()
-
wchar_t *wmemcpy(wchar_t *str1, const wchar_t *str2, size_t num)
Equivalent: memcpy()
-
wchar_t *wmemmove(wchar_t *str1, const wchar_t *str2, size_t num)
Equivalent: memmove()
-
wchar_t *wmemset(wchar_t *str, wchar_t ch, size_t num)
Equivalent: memset()
Example C++ Code:
Here’s an example C++ code snippet demonstrating the use of `wmemcpy`:
#include <cwchar>
#include <iostream>
int main() {
wchar_t source[] = L"Hello, Wide World!";
wchar_t destination[20];
// Copying wide characters
wmemcpy(destination, source, wcslen(source) + 1);
std::wcout << L"Source: " << source << std::endl;
std::wcout << L"Destination: " << destination << std::endl;
return 0;
}
This demonstrates the usage of `wmemcpy()` to copy wide-character strings, a direct equivalent to `memcpy()` for `char`.
Generic Poitner Type - Exercise