1 - Separating Function Defs From Class Def
1 - Separating Function Defs From Class Def
Programming
Mohammad Salman
Dean’s Fellow
Providing Function
Definitions Separate from
Class Definition
The class definition will only have function prototypes (or function
declarations).
https://www.learncpp.com/cpp-tutorial/classes-and-header-files/
Note that this is the same class that you may have written in Lab 5.
Observe how long and unwieldy class definitions may become to read and follow.
class Stack int top() const // Regular ctor with one param (not default)
{ { Stack(int s)
private: // empty : m_size{ s },
int m_size; if(m_top == -1) m_top{ -1 },
int m_top; return -1; m_arr{ new int[s] }
int* m_arr; // not empty {
else }
public: return m_arr[m_top];
void push(int element) } // Copy ctor
{ Stack(const Stack& st)
if(m_top + 1 < m_size) bool isEmpty() const : m_size{ st.m_size },
{ { m_top{ st.m_top },
m_arr[m_top + 1] = element; // empty m_arr{ new int[st.m_size] }
m_top++; if(m_top == -1) {
} return true; for(int i{}; i<st.m_size; i++)
} {
return false; m_arr[i] = st.m_arr[i];
int pop() } }
{ }
int val{ -1 };
~Stack()
if(m_top > -1) // not empty {
{ delete[] m_arr;
val = m_arr[m_top]; }
m_top--;
Are the user-defined dtor and copy };
} ctor required for this class?
return val; Also, think about what will happen if
}
the user enters size = 0? How will
you cater for this?
The language provides us a way to simplify this problem, and improve readability and code management.
Just keep the attributes and prototypes of methods within your class.
class Stack int top() const // Regular ctor with one param (not default)
{ { Stack(int s)
private: // empty : m_size{ s },
int m_size; if(m_top == -1) m_top{ -1 },
int m_top; return -1; m_arr{ new int[s] }
int* m_arr; // not empty {
else }
public: return m_arr[m_top];
void push(int element) } // Copy ctor
{ Stack(const Stack& st)
if(m_top + 1 < m_size) bool isEmpty() const : m_size{ st.m_size },
{ { m_top{ st.m_top },
m_arr[m_top + 1] = element; // empty m_arr{ new int[st.m_size] }
m_top++; if(m_top == -1) {
} return true; for(int i{}; i<st.m_size; i++)
} {
return false; m_arr[i] = st.m_arr[i];
int pop() } }
{ }
int val{ -1 };
~Stack()
if(m_top > -1) // not empty {
{ delete[] m_arr;
val = m_arr[m_top]; }
m_top--;
Are the user-defined dtor and copy };
} ctor required for this class?
return val; Also, think about what will happen if
}
the user enters size = 0? How will
you cater for this?
With just the function prototypes in the class definition, the class has become more compact and more readable.
Note that this definition is in a separate header file.
// Stack.h
class Stack
{
private: I can easily see that these are the public behaviors I have
int m_size; access to (my primary interest as a user of this class – the
int m_top; programmer).
int* m_arr;
I can see the return type, name, parameters, const-ness of
public:
void push(int element); these methods.
int pop();
int top() const; I can also see the constructors which tell me how can I create
bool isEmpty() const; objects of this class.
• Usually, definitions of one line and trivial functions are left inside the class.
• e.g. simple ctors, simple dtors, getters, setters, etc.
• But it’s up to you.
• By the way, you may put the method implementations within the
header file as well if you have a very small class.
• The class definition (with just the function prototypes) would be followed by
member function definitions outside the class.
• All could be in the same file (Class.h).