Download presentation
Presentation is loading. Please wait.
Published byMadison Knight Modified over 9 years ago
1
Separate Compilation
2
A key concept in programming Two kinds of languages, compilation (C, Pascal, …) and interpretation (Lisp, …, Matlab, Phython, Javascript…) It was a ‘milestone’ for procedural programming, some old ones like Pascal cannot, … It is in fact a kind of ‘abstract data type’, to separate the function “implementations” from its “definitions” It is also impossible for large projet without it
3
Translating a Library 3 Program Source File Library Header File Library Implementation File C++ Compiler Linker Program Object File Library Object File Program Executable File g++ -c.o e.g., g++ foo.cpp bar.o fb.o
4
Motivation #include using namespace std; bool even(int); bool odd(int x) { bool res; if(x == 0) res=false; else even(x-1); return res; } bool even(int x) { bool res; if (x == 0) res=true; else odd(x-1); return res; } int main() { int x; cin >> x; cout >> odd(x) >> endl; cout >> even(x) >> endl; return 0; }
5
#include using namespace std; bool even(int); bool odd(int); int main() { int x; cin >> x; cout >> odd(x) >> endl; cout >> even(x) >> endl; return 0; } bool odd(int x) { bool res; if(x == 0) res=false; else even(x-1); return res; } bool even(int x) { bool res; if (x == 0) res=true; else odd(x-1); return res; } It’s about ‘Organization’, organization of files!
6
One file many files … 3 functions: odd() even() main() “ main.cpp ” odd() “ odd.cpp ” even() “ even.cpp ” main() “ main.cpp ” Reasons: 1. Reuse code for other programs 2. Divide work among programmers 3. Better maintenance, localize changes
7
#include using namespace std; bool odd(int); bool even(int); int main() { int x; while (cin >> x) { num_calls = 0; cout << boolalpha << odd(x) << endl; } return 0; } main() “ main.cpp ” #include using namespace std; bool odd(int); bool even(int x) { … } #include using namespace std; bool even(int); bool odd(int x) { … } even() “ even.cpp ” odd() “ odd.cpp ”
8
g++ -c main.cpp main.o g++ -c even.cpp even.o g++ -c odd.cpp odd.o g++ -o odd-even main.o even.o odd.o odd-even -c generates an object file -o generates an executable by linking all object files g++ file.cpp a.out
9
Separate compilation by ‘makefile’ If only “ main.cpp ” is modified, just need to re-compile “ main.cpp ” and re-link by: g++ -c main.cpp g++ -o odd-even main.o even.o odd.o No need to re-compile the object files, i.e. even.o and odd.o ‘makefile’ will automate all these things!!! ‘makefile’ is also a program in ‘script’ language that organizes your ‘command files’!
10
Using header files We do not want to repeat writing the same declarations in multiple files. Should a declaration require updating, one has to go through all files that have the declaration and make the change. More importantly, maintaining duplicate information in multiple files is error-prone. Many declarations are repeated in “odd.cpp” and “even.cpp”, but
11
#include preprocessor directive include header files Instructs C++ preprocessor to replace directive with a copy of the contents of the specified file Quotes for user-defined header files Preprocessor first looks in current directory If the file is not found, looks in C++ Standard Library directory Angle brackets for C++ Standard Library Preprocessor looks only in C++ Standard Library directory #include 11
12
#include using namespace std; bool even(int); bool odd(int x) #include “myInclude.h” bool odd(int x) { bool res; if(x == 0) res=false; else even(x-1); return res; } #include “myInclude.h” int main() { int x; cin >> x; cout >> odd(x) >> endl; cout >> even(x) >> endl; return 0; } #include “myInclude.h” bool even(int x) { bool res; if (x == 0) res=true; else odd(x-1); return res; } myInclude.hmain.cppodd.cppeven.cpp Example of headfile
13
Avoiding recursive inclusions … It is ok to have multiple declarations of a function prototype, but not for its definition In the.h file, put the prototypes there .h files are likely to be multiply-included In creating the.o file, there may be nested #include statement The nested #include statement may be recursive In main.cpp, #include “foo.h” In foo.h, #include “bar.h” In bar.h, #include “foo.h” To break the infinite “recursive” inclusion, use #ifndefine #define to define a “variable” in the compilation process of.o file If a variable has been defined, the compiler will skip the code segment between #ifndefine and #endif. 13
14
#define preprocessor directive if XYZ is undefined, we process the file. Otherwise we do not process the file (jumping to the #endif). XYZ should not appear in any other files. 14 #ifndef XYZ #define XYZ f1(); f2(); … #endif
15
File scope: external/internal Each file must know the existence of every variable, constant and function that it uses! Global constants: repeat their definitions (global constants are ‘ local ’ to the file, internal!) External (global) variables: add keyword “ extern ” External functions: add function prototypes (with or without “ extern ” ) “ extern ” it ’ s (just) a declaration, but not a definition! equivalently, it means the variable / function is global and is defined in another file.
16
16 #include #include "library.h" using namespace std; int Int=99; int main(){ cout << "Hello"<<endl; cout << f(100) << endl; return 0; } #include "library.h" int f(int i){ return (Int + i); } main.cpp source.cpp Output: Hello 199 library.h extern int Int; int f(int);
17
Separate compilation with classes
18
Interface and Implementation In C++ it is more common to separate the class interface from its implementation. Abstract data type The interface lists the class and its members (data and functions). The implementation provides implementations of the functions. 18 What to do? How to do?
19
19 Class interface header file *.h Class implementation source code file *.cpp Client/application/user driver file main.cpp The implementation is hidden from the users!
20
Separate Files .cpp source-code files .h header files Separate files in which class definitions are placed Allow compiler to recognize the classes when used elsewhere Generally have.h filename extensions Driver files Program used to test software (such as classes) Contains a main function so it can be executed 20
21
Class Libraries 21 Class declarations placed in header file Given. h extension Contains data items and prototypes Implementation file Same prefix name as header file Given. cpp extension Programs which use this class library called client programs
22
Example The interface, implementation and driver separated into three files Interface contains data members and member function prototypes only Note the #ifndef statements to prevent multiple inclusions 22 #ifndef GRADEBOOK_H #define GRADEBOOK_H class GradeBook { public: GradeBook( string ); void setCourseName( string ); string getCourseName(); void displayMessage(); private: string courseName; }; #endif Gradebook6.h (with Validity Checking)
23
set functions perform validity checking to keep courseName in a consistent state GradeBook implementation is placed in a separate file Include the header file to access the class name GradeBook Binary scope resolution operator :: “ties” a function to its class 23 #include "GradeBook6.h" // include definition of class GradeBook void GradeBook::setCourseName( string name ) { // if name has 25 or fewer characters if ( name.length() <= 25 ) courseName = name; // if name has more than 25 characters if ( name.length() > 25 ) { // set courseName to first 25 characters of parameter name courseName = name.substr( 0, 25 ); cout << "Name \"" << name << "\" exceeds maximum length (25).\n" << "Limiting courseName to first 25 characters."; } Gradebook6.cpp
24
Include the header file to use the class GradeBook 24 #include "GradeBook6.h" // include definition of class GradeBook int main() { // initial course name of gradeBook1 is too long GradeBook gradeBook1( "COMP104 Introduction to Programming in C++" ); GradeBook gradeBook2( "COMP152 OOP and Data Structures" ); cout << "gradeBook1's initial course name is: " << gradeBook1.getCourseName() << "\ngradeBook2's initial course name is: " << gradeBook2.getCourseName() << endl; driver6.cpp (1/2)
25
Call set function to perform validity checking directly In Linux, compile them all together using g++ Gradebook6.cpp driver6.cpp Or using object files: g++ -c Gradebook6.cpp; g++ -c driver6.cpp; g++ driver6.o driver6.o 25 // modify myGradeBook's courseName (with a valid-length string) gradeBook1.setCourseName( "COMP104 C++ Programming" ); // display each GradeBook's courseName cout << "\ngradeBook1's course name is: " << gradeBook1.getCourseName() << "\ngradeBook2's course name is: " << gradeBook2.getCourseName() << endl; return 0; } driver6.cpp (2/2)
26
26 Name "COMP104 Introduction to Programming in C++" exceeds maximum length (25). Limiting courseName to first 25 characters. gradeBook1's initial course name is: COMP104 Introduction to P gradeBook2's initial course name is: COMP152 OOP and Data Stru gradeBook1's course name is: COMP104 C++ Programming gradeBook2's course name is: COMP152 OOP and Data Stru driver6.cpp Sample Output
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.