Lesson 5 | External member functions |
Objective | Rewrite Person class using external member function |
External Member Functions in C++
In C++, the term "external member function" is not a standard nomenclature in the language's specification. However, the term "external" in conjunction with functions can be related to the "extern" keyword which specifies linkage information about a function or a variable.
Let's dive deep into this concept to elucidate its purpose and application.
- "extern" Keyword and Linkage: In C++, the `extern` keyword denotes that a particular function or variable is defined elsewhere, possibly in another source file or a library. This keyword primarily deals with linkage – that is, connecting references of an entity to its definition.
- Member Functions and `extern`:
When we speak of member functions of a class, they are typically defined either:
- Inline: Defined within the class definition itself. These functions are implicitly inline, which may suggest to the compiler to inline-expand the function's code at the point of invocation.
- Outside the Class: Defined outside the class using the `ClassName::FunctionName` syntax. This approach separates the declaration from the definition, allowing for more modular code.
- However, the `extern` keyword is not typically associated with member functions. Instead, it's more common with global functions or variables to denote external linkage.
- What's an "External Member Function"?
If someone uses the term "external member function," they might be referring to a member function that's defined outside the class definition. Such a separation is done for various reasons:
- Readability: Separating lengthy function definitions from the class declaration can make the class declaration easier to read and understand.
- Compilation: The separation allows for independent compilation of class definitions and member function implementations, which can reduce compile times in large projects.
- Encapsulation: While the function's prototype is visible in the class declaration, its implementation details remain hidden when defined in a source file.
C++ member function may not be redeclared outside its class
In C++, member functions of a class cannot be redeclared outside the class because of how the language is designed to handle encapsulation and scope. Here are the key reasons:
- Encapsulation and Scope: One of the core principles of object-oriented programming is encapsulation, which is the idea that the internal workings of a class should be hidden from the outside world. Declaring member functions within the class definition ensures that the function signatures are known and controlled by the class itself. Allowing redeclaration outside the class would break this encapsulation principle and potentially lead to confusion about what functions belong to the class.
- Consistency and Clarity: Declaring all member functions within the class ensures that all declarations are centralized, making it clear and straightforward for developers to see what operations a class supports. If member functions could be redeclared outside the class, it would make the codebase harder to understand and maintain, as the complete interface of the class would be scattered across different parts of the code.
- Linkage and Symbol Resolution: C++ relies on name mangling and linkage to resolve function calls. When a member function is declared inside a class, the compiler generates a unique name for it that includes the class name to avoid name clashes with other functions. Allowing redeclaration outside the class would complicate this process and could lead to ambiguity or linkage errors.
- Language Rules and Standards: The C++ language standard explicitly requires that member functions be declared within the class definition. This rule simplifies the compiler's job in parsing and compiling the code, ensuring that the language remains consistent and predictable. Deviating from this rule would require significant changes to the language specification and compiler implementations.
- Implementation and Definition: While member functions must be declared within the class, their implementations can be provided outside the class definition using the scope resolution operator (::). This allows for clear separation between the interface (declaration within the class) and implementation (definition outside the class), while still maintaining a clear and consistent structure.
Here's an example illustrating the correct way to declare and define a member function:
class MyClass {
public:
void myFunction(); // Declaration inside the class
};
// Definition outside the class using the scope resolution operator
void MyClass::myFunction() {
// Function implementation
}
In this example, `myFunction` is declared within the class `MyClass`, ensuring encapsulation and clarity, while its implementation is defined outside the class, maintaining a clear separation between the interface and implementation.
C++ Member Function Example
// MyClass.h
class MyClass {
public:
void myFunction(); // Declaration of the member function
};
// MyClass.cpp
#include "MyClass.h"
void MyClass::myFunction() {
// Implementation of the member function
}
In the above example, `myFunction` can be viewed as an "external member function" because it's declared inside `MyClass` but defined externally in another source file.
While the term "external member function" isn't standard jargon in C++, it may be used informally to describe member functions defined outside their class declaration. Proper understanding of this distinction aids in writing organized, maintainable, and efficient C++ programs.
Use an external member function to print out the member data of the Person class.
To define a member function outside the
class
, the scope resolution operator is used. To illustrate this, let us revisit the
ch_stack class
from the previous module. We can change the declaration of
push
, inside the declaration of
class ch_stack
, to just a function prototype and define
push
elsewhere. When we define it, we write the name out fully using the scope resolution operator.
In this case, the function is not
implicitly inline.
const int max_len = 40;
class ch_stack {
public:
void reset() { top = EMPTY; }
void push(char c);
char pop() {
assert(top!= EMPTY);
return s[top--];
}
char top_of() {
assert(top!= EMPTY);
return s[top];
}
bool empty()
{ return (top == EMPTY); }
bool full()
{ return (top == FULL); }
private:
char s[max_len];
int top;
enum { EMPTY = -1, FULL = max_len - 1 };
};
void ch_stack::push(char c) //not inline {
assert(top != FULL);
top++; s[top] = c;
}
External Member Function - Exercise