Today lecture
What is a Multi-File C++ Program?
1. A multi-file program means splitting your code into multiple source files (usually .h and
.cpp files) instead of writing everything inside one [Link].
2. Example structure:
Student.h → Declarations (blueprint)
[Link] → Definitions (implementation)
[Link] → Uses the class
3. Benefits of Using Multi-File C++ Programs
A. Modularity (Organized Code)
Each class or module is in its own pair of files — .h for interface and .cpp for implementation.
Example:
If you have classes Student, Teacher, and Course, each can live in its own files.
This keeps the code base neat and easy to navigate.
B. Team Collaboration
In a large software team, multiple developers can work on different modules simultaneously:
• One works on [Link]
• Another works on [Link]
• Another works on [Link]
No one overwrites each other’s code — this supports parallel development.
C. Separation of Interface (.h)and Implementation(.cpp)
.h (header) = Interface — tells “what” the class or function does.
.cpp = Implementation — shows “how” it does it.
char name[50]; // character array for storing name
udate it
char *name
still the interface to interact with name is setName(“Ahmad”)
This separation improves readability and makes your program easier to understand and
maintain.
4. Encapsulation & Information Hiding
The user (e.g., [Link]) only includes the header file and doesn’t see the implementation
details inside .cpp.
Users can use the class without needing to know how it works internally — similar to how you
use a library like <iostream>.
5. Easier Debugging and Maintenance
Each module (e.g., [Link]) can be tested and debugged independently, without affecting
other parts of the project.
If something breaks, you know exactly which file to fix.
Multi-File C++ Program:
Project5
├───Header Files
│ └── Student.h
├───Source Files
│ ├── [Link]
│ └── [Link]
Include only the header file in [Link]; including the .cpp file causes duplicate definitions and
linker errors.
Including Files in a Multi-File C++ Program
• In a multi-file program, only the header file (e.g., Student.h) should be included in
[Link].
• The .cpp implementation file (e.g., [Link]) should never be included directly in
[Link].
Reason:
When [Link] is compiled, it already contains the function definitions of the Student class.
If you also include [Link] in [Link], the compiler will insert the same definitions into
[Link] as well — causing duplicate definitions of the class and its member functions.
Result:
The linker detects these duplicates and throws an error such as:
#pragma once helps to avoid the multiple inclusion of the same header within that one
file's compilation,
Student.h
#pragma once //Prevent multiple inclusions of the same header file in a single compilation unit
— a situation known as a “multiple inclusion” or “redefinition” error.
// compiler directive that tells the C++ compiler: “Include this header file only once per
compilation — even if it’s included multiple times in different parts of the program.”
#define _CRT_SECURE_NO_WARNINGS // as strcpy()etc function don’t perform boundschecking
#include <iostream>
#include <cstring>
using namespace std;
class Student {
private:
int rollNo;
char name[50];
public:
Student(int r = 0, const char* n = "Unknown");
void display() const; // const function declaration
};
[Link]
#include "Student.h"
Student::Student(int r, const char* n) {
rollNo = r;
strcpy(name, n);
}
void Student::display() const { // const in definition
cout << "Roll No: " << rollNo << ", Name: " << name << endl;
[Link]
#include "Student.h"
int main() {
const Student s1(101, "Ali");
[Link](); // works because display() is const
return 0;
Need of Pragma once
// Student.h
class Student {};
// Account.h
#include "Student.h"
class Account { };
// [Link]
#include "Student.h"
#include "Account.h"
int main() { ... }
When the compiler compiles [Link], it performs preprocessing — it copies and pastes the contents of all included headers into
one giant file before actual compilation.
// (expanded version during preprocessing)
class Student { ... }; // from first include
class Student { ... }; // again from Account.h include DUPLICATE
class Account { ... };
int main() { ... }
// Now you get a redefinition error — because Student appears twice in the same compilation unit.
Solution is #pragma once fixes it
If you add #pragma once at the top of Student.h:
#pragma once
class Student { ... };
// after preprocessing
class Student { ... }; // from the first include only
class Account { ... };
int main() { ... }
1. Use of this
Student s1;
Student s2;;
s2 = [Link](“ali”);
Student s2 =[Link](“ali”);
Student s2= [Link](“ali”).setRollNo(2);
2. const key
a. const member function
- Compiler helps us to avoid our own mistake
- bool isRollNo(int r)
{
If (rollNo =r){ return true;} // no error but it is logical error
}
- Solution:
- bool isRollNo(int r) const // const Student * const this;
{
If (rollNo == r){ return true;}
}
b. return the const
const char * getName() const // to facility information hidding
{ return name}
main()
{
Student s1;
const char *n=[Link](); // main only read the name
Note:
a) const key word with the function make the this as a constant pointer:
const Student *const this;.
b) Constant function can’t call the non constant member function
3. const data members
i. member initialization list
b. const objects
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Student
{
char* name;
const int rollNo;
public:
Student(const char* n = NULL, int r = 0);
~Student();
bool isRollNo(int) const;
int getRollNo() const;
void display()const;
};
Student::Student(const char* n, int r) :rollNo(r)
{
if (n != NULL)
{
int len = strlen(n);
this->name = new char[len + 1];
strcpy(this->name, n);
}
//rollNo = r; // ERROR
cout << name << " constructor " << endl;
}
Student::~Student()
{
cout << name << " Destructor " << endl;
if (name)
{
delete[] name;
name = NULL;
}
}
void Student::display() const
{
cout << name << " " << rollNo << endl;
}
//int Student::getRollNo(const Student* const this) const // compiler created code
int Student::getRollNo() const
{
return rollNo;
}
//bool Student::isRollNo(int r, const Student *const this) const // compiler created code
bool Student::isRollNo(int r) const
{
//display();
if (this->rollNo == r) // rollNo is read only
return true;
else
return false;
}
int main()
{
Student s1("moosa", 1);
[Link]();
const Student s2("ahmad", 2);
[Link]();
}
4.
const Objects
const objects can access only const member functions so chances of change of state of const
objects once they are created are eliminated.
We make getRollNo function constant so that we can access it using constant objects,
#include <cstdlib>
#include <iostream>
using namespace std;
class Student
{
int rollNo;
public::
int getRollNo()
{
return rollNo;
}
void display()const
{
Cout<< rollNo;
}
};
int main()
{const Student aStudent(5);
int a = [Link](); //error
[Link]() ; // ok
Constant member functions
Make all functions that don’t change the state of the object constant This will enable constant
objects to access more member functions