How to include CPP files that don't exist yet? - c++

I have a class Game that serves as an interface, and two classes Poker and BlackJack that implement this interface. I have this method that returns a list of Game objects that I can then use:
#include "Poker.h"
#include "BlackJack.h"
...
std::vector<Game*> getGames() {
std::vector<Game*> gs;
Game* p = new Poker();
gs.push_back(p);
Game* b = new BlackJack();
gs.push_back(b);
return gs;
}
At the moment it can only return a list containing these two classes. I want to be able to write more implementations of this interface or get other people's implementations, drop the CPP file in some directory, and be able to call this method, except now with the vector also containing an instance of this new class.
So far I have:
std::string path = "/Games";
std::vector<std::string> filePaths;
for (const auto& file : std::filesystem::directory_iterator(path)) {
filePaths.push_back(file.path().string());
}
Which creates a list of file paths in some directory.
I have no idea how to continue from here since in order to use these files I would have to add an include statement each time. The end goal is to have a program that users could very easily import their own games onto. How could I go about doing this?

How to include CPP files that don't exist yet?
You cannot. You can only include files that already exist.
In theory, you could achieve what you want using meta-programming. That is: Write a program that writes a header that includes all the headers. Then include the header generated by the meta-program. To update the list, re-run the meta-program. You can automate the build process to do it before compilation.
However, I don't see how it could be a good idea in this case. In order for getGames to change, you would have to change the function anyway. Just add the include directive when you add code that uses the header... Unless you use meta programming to generate the function as well, which could be reasonble. But take into consideration the complexity added by the meta-programming before choosing such design.
The end goal is to have a program that users could very easily import their own games onto.
If the goal is for the users to do this after your program has been compiled, then it won't work at all. You'll need to describe your goal more thoroughly for me to suggest a better approach.
P.S. Avoid the use of bare owning pointers. In this case, I recommend to use std::vector<std::unique_ptr<Game>> instead.

Related

Hiding the Contents of a Header File

I am a tutor and I'm trying to write something to help students learn C++. Suppose I have a .cpp file that includes two .h files, which we will call "solution.h" and "student_answer.h". The "solution.h" file contains a class called "Solution" which implements member functions and variables that solve a problem. Students are to implement their own solution to the same problem in a separate "student_answer.h" file, in a class which we will call "Student".
The .cpp file should then take the two class definitions, "Solution" (the class defined in solution.h) and "Student" (the class defined in student_answer.h), and run the two implementations to verify whether the student answer is correct, and it should provide detailed output in cases where the student answer has a bug. However, I want to be able to hide the contents of the solution.h file (or the "Solution" class) from the students while still providing them with the .cpp file that they can compile and run their own solution with.
Currently, I have something like this:
#include "solution.h"
#include "student_answer.h"
// ...
int main() {
Solution s;
Student a;
// run member functions of s and a, compare results to verify if student
// implementation is correct (and print helpful output if there is a bug)
...
}
Is there a way to do the same thing without having to reveal the solution.h file to the students? Is there a better approach to doing this?
Thanks!
Is there a way to do the same thing without having to reveal the solution.h file to the students?
No.
Best you could do is to not put any implementation details into solution.h and instead provide a pre-compiled library for comparison. That would prevent students from seeing the solution except for the API, which is presumably part of instructions for the student anyway.
This does have a challenge that the pre-compiled library must be compatible with the systems that the students use. This can be solved by instructing the students to use a provided VM or container image.
However, this approach does not prevent the students from implementing their API by delegating to the solution API.
There's really no need to provide the correct solution. Write to solution for yourself only; write tests that are required to pass with either your solution or the student's; Test the tests with your solution; Provide only the tests to the students, not your solution.
Create a static or dynamic library of Solution.h, compile it, and link it with the project. The students now get the header of the solution with declarations, but not definitions.
The library topic is a little bit too complex to explain in one answer. Watch the video from TheChernoProject ( https://www.youtube.com/watch?v=Wt4dxDNmDA8 ) for it.
Another way would be, making the code unreadable (defines) or put it in asm blocks.

Hide class implementation from its interface

I have this code for an interface of a class in a header file and its implementation in a separate source file :
First :The Header file "Gradebook.h"
#include <string>
using namespace std;
class Gradebook{
public:
Gradebook(string);
void setCoursename(string);
string getCoursename();
void displayMessage();
private:
string nameofCourse;
};
Second :The implementation "Gradebook.cpp"
#include "stdafx.h"
#include "Gradebook.h"
#include <iostream>
using namespace std;
Gradebook::Gradebook(string name){
setCoursename(name);
}
void Gradebook::setCoursename(string name){
nameofCourse = name;
}
string Gradebook::getCoursename(){
return nameofCourse;
}
void Gradebook::displayMessage(){
cout << "Display message function shows :" << getCoursename() << endl;
}
how can i link these two separate files in order to use only "Gradebook.h" in other project , and hide my implementation from the client-programmer ?
There are several answers. It would help to know why you actually want to hide the implementation. Here's the reasons why you might want to do this I can think of offhand.
Protecting trade secrets: Forget it. To be able to execute your code, the computer has to be able to run it. Effectively you can strip away comments, method names and variable names by compiling the code as a static library, even run an obfuscator over it to obscure the control flow (at the cost of slowing it down by adding unneeded jumps), but in the end the code (or the machine code generated from it) has to stay sort of readable or it couldn't be executed.
Make it easier to use your code: If you have several source files and might add more files, and you want your clients to just be able to drop in one file to get all the newest changes without having to add individual source files, compile it as a static or dynamic library. Then you can hand someone the library plus the headers and they can just use them.
You can also create an "umbrella header" that includes all the other headers. That way, clients can simply add the path to your library's includes folder to their compiler invocation/project file and include the one header, which includes all others. If you add or split up a header, you just change the umbrella to include the new headers and all projects that use it keep working.
Note that using a library will limit your clients: They can't step through your code in the debugger easily, they can't fix and compile stuff easily. If they need your code to run on a new platform, or want to use different optimization settings in the compiler, they can't just recompile it.
On the other hand if you plan to sell your library, you might want to hold on to your sources. Customers who don't care about the security of having the code if you ever go out of business can get a cheaper version of the library without the source code, you can charge them extra if they want any of the other features by making them buy a version for the new platforms that you coded for them, etc.
Prevent clients from accidentally relying on implementation details: You don't really need to do anything for this except split up your code into public and private files. Usually your implementation file is private and your headers are public, but you may have some private headers for internal classes.
Since C++ does not allow defining instance variables or methods that aren't declared in the header's class declaration like other languages do that support categories or class extensions, you may have to resort to the Private Implementation (aka 'pimpl') pattern.
What this usually means is that you declare one class that defines the public API that simply wraps a pointer to the actual class that contains the real implementation and calls through to it. It usually only has one instance variable, pimpl, which is the pointer to the other class. You simply forward-declare the private class using class Foo; and thus your clients' code doesn't know anything about the private class (unless they explicitly peek into the implementation file or private header, e.g. when fixing a bug).
Create a single-file class I mention this last because it is generally a stupid thing to do, but just in theory, you could also move the implementation file's content into the header. Then clients only need to include the header and get all the sources. This has lots of downsides, though, like making code harder to read, slowing down compile times, and requiring the client to deal with duplicate definitions of the class caused by including the file from several .cpp files. In short: Don't do it.

Header and Code in C++ classes

I just started on a few C++ tutorials, and I have run into something that I just can't seem to make much sense of.
In C++ it seems people are using a code file and a header file, for me this just seem inconvinient. Why would I want to swap around between two files just to write a simple getter method.
Is it considered the "correct" way to use headers in C++? Or is it just the tutorial I have picked up that uses this?
I get the idea of splitting code to make it look more clean, but is it good for anything else other than that?
Thanks in advance.
There are some reasons for using hpp(header)- and cpp(code)-files. One of them is the following: A library (dll- or so-file) cannot be "used" like a jar-file in java. If you write a library, you have to provide declarations of the classes, methos,... in form of a hpp-file.
Think about using the class you wrote in other files. If you had the class definition in a separate file, you could help the compiler to figure out how to use the class by including the header file in places where you are planning to use this code.
The compiler only needs to know whether you are using the classes right(it does not care about how to run it, until linking), therefore all you need to give the compiler is the declaration of the class(header file), to do the error checking. When you say "include", the preprocessor just copies and pastes the header file contents into the new file, so that the new file now knows how to use the class you wrote.
A header file in c++ stores alot of information, if c++ have been made using every single "header" file in c++ in each program you make, when you then write a function from iostream for example, the program will go through every single header file just to find the right header file. so instead they made the #inlcude function in c++, so you could specify where your functions are from.
And when you create a program you could make own header files, so the code is more nicely set up. and then instead of having to make alot of lines of code in one main source file, you could import others. like if you are making a game, one header file for Animals and in that header file you have a Class for Cats, and one for dogs. having a more clean code.
In C/C++, headers are used to share the class structure (among other things) between classes.
so one can use
include "classFOO.h"
in classBAR.h (or classBAR.cpp) and use classFOO.

C++ #include, how does nested includes work?

So I'm learning C++ and learning to also use SQLite in my practices for data persistence across application runs, which is lots of fun.
But I bumped into this issue:
The program is a Grade Book, classic Ditel C++ book exercise. I'm structuring my classes as follows:
~/classes/Database.h/cpp // A small wrapper for sqlite3
~/classes/Student.h/cpp // The Student object with name and grades (Uses Database)
~/classes/GradeBook.h/cpp // Takes care of most of the application logic and UI (Uses Database and Student)
~/main.cpp // contains just the main function and base Instances of Database and GradeBook
This is so I can instantiate a Single Database Object from main() and pass it by reference to GradeBook and Student so they can use the Database functions. I tried all possible order of includes and as it turns out only this order has works for me.
Student includes Database.
GradeBook includes Student, gets access to Database.
main.cpp includes GradeBook, gets access to both Database and Student.
The question is, is this right? It seems utterly counter-intuitive that the includes seems to "cascade" backwards from deepest classes to the main.cpp file, in other words, Am I doing this right, or am I missing something?
If so, a little explanation or pointers on how this "cascading" works would be pretty awesome.
Thanks!
First, your header files should use include guards to prevent multiple inclusion:
#ifndef MY_HEADER_H
#define MY_HDEADER_H
// code...
#endif // this file will only ever be copied in once to another file
Secondly, you should explicitly include all of the header files that you need to do what you want to do. Relying on header A to include header B for you is just clunky and, since you're using include guards, you never have to worry about including the same file twice.
So, to answer your question, no, it's not "right" in the sense that it could be "better". main.cpp should include the all of the header files that it needs. All of them. #include is a simple text substitution mechanism. When you #include a file it is literally pasted in. That's it.

Turning one file with lots of classes to many files with one class per file

How do I turn one file with lots of classes to many files with one class per file? (C\C++)
So I have that file with such structure: Some includes and then lots of classes that sometimes call each other:
#include <wchar.h>
#include <stdlib.h>
//...
class PG_1 {
//...
}
class PG_2 {
//...
}
//......
class PG_N {
//...
}
If you're not using revision control (tsk tsk):
Back up your entire project in case you mess up.
Cut and paste each class into its own classname.h and classname.cpp files. Replace classname with the name of the class. Update the include guards.
Add the #include directives that you think are necessary for each class's dependencies.
Delete multiclass.h and multiclass.cpp.
Add the single-class files to your project or makefile. Remove the multi-class files from your project or makefile.
Build the project or makefile.
If it fails to build, fix the problem (e.g. a missing #include) and go to step 6.
Once it builds, run your tests.
If the tests fail, diagnose and fix the problem, and go to step 6.
If you are using a revision control system that supports file-level branching (such as Perforce, or maybe Subversion?), you should take care to preserve the revision history, so that other developers can find old changes:
Do the rest of these steps in a development branch, not the trunk.
For each class name in multiclass.h and multiclass.cpp, integrate multiclass.h and multiclass.cpp into a separate classname.h and classname.cpp for that class.
Submit a changelist containing all of these integrations. This makes N copies of the original file, and they all have a revision history pointing to the original.
Check each new file out for edit.
Remove everything from each new file except the code that is needed for that particular class, and update the include guards.
Add the #include directives that you think are necessary for each class's dependencies.
Check the old multiclass.h and multiclass.cpp out for delete.
Check out the project or makefile for edit.
Add the single-class files to your project or makefile. Remove the multi-class files from your project or makefile.
Build the project or makefile.
If it fails to build, fix the problem (e.g. a missing #include) and go to step 10.
Once it builds, run your tests.
If the tests fail, diagnose and fix the problem, and go to step 10.
Submit the changelist with all of the edits.
If you are using a revision control system that doesn't support file-level branching, then some combination of the two methods should work. Hopefully you get the idea.
How do I turn one file with lots of
classes to many files with one class
per file?
Edit: Something I should mention on refactoring in general. There's no such thing as a big step in refactoring (not unless you want to destroy your code-base). You should always make transactional transformations to the code, with validity checks in between (transactional means they are clearly delimited and can be committed and rolled-back at any point). If you have big steps that means you haven't broken them enough into small steps. Also, each step should do one thing and one thing only. (end edit).
Steps:
back up everything (all affected files)
This means perform a commit in your source-control system. If you don't use any source control, install mercurial before continuing (go ahead, we'll wait ;)) - you can thank me later :D
create new files (.h and .cpp file) for the first class you want to remove, then include the new .h file in your old header (the one with many classes).
move the class declaration in the .h file and the class implementation in the new .cpp file.
remove the declaration / implementation from the old file. At this point compile the code, and copy #include dirrectives from the old files to the new files until everything compiles. At this point you should have your class moved to separate files, and included in the old header file. Do not copy all includes, only enough for your moved class to compile correctly.
compile the code (eventually run the application and make sure everything runs).
perform a commit in your source control system.
remove the included new file from your old (multiple classes) header file and compile. go through the code and include the new file in whatever files you get errors.
repeat the steps 5 and 6.
pick new class, go back to step 1.
Possible mistakes and caveats:
you may be tempted to make other changes to the new code while moving it to new files. Do not make any changes. At the end of a cycle (after step 8) you should have the same code you had before step 1, just in different files. Any changes you make to the code in between the steps will be difficult to separate from the refactoring, difficult to track later and difficult to reverse. It's not worth the hassle, especially when you can make the same changes once the refactoring cycle is completed (with no other problems).
you may be tempted to work on multiple classes at the same time. Don't do that either. If you work in cycles you are always able to revert the code (in your SCM) to versions of the code that worked and you have modular changes. It is also very easy to track changes and check you didn't introduce new bugs if you go one class at a time.
Sidenote: If you use a branching SCM you will be able to work on the tasks in parallel, to interrupt your refactoring (commit everything - let's call this "branch head A"), go back to the code before you started refactoring, make some other changes, commit those (call them "branch head B"), then go back to branch head A, finish your refactoring, then merge A and B and you're in business.
There are several ways to accomplish that.
The most straight forward would be to read the file one line at the time and detect if that line starts a class.
Then start detecting matching braces... you know if you find { +1 and } -1 until you reach zero. Yes, there's more to that, but that's the main part.
Select that block and write it on another file.
On the other hand, IF you're using Visual Studio, would be to create a macro and use the DTE to peruse the FileCodeModel of the currently open file, and create a file for each top level class in that.
Two basic coding style patterns are possible:
Class declarations in headers, member function/static data instantiation in .cpp files.
Class definitions with in-line implementation in headers
Option 2 may lead to code bloat since if you use the class in multiple compilation units you may get multiple copies of the implementation in the final link; it is down to the linker to eradicate this and it may or may not do so - YMMV. It also allows users of the class access to the implementation, which may be undesirable in some cases.
A combination of the two with simple getter/setter functions in-lined and larger code bodies in separate compilation units is an option. Often if I have a constructor that is entirely implemented by the initialiser list, I will include its empty body in-line.
Example for class cExampleClass:
cExampleClass.h
class cExampleClass
{
public:
cExampleClass() ;
~cExampleClass() ;
void memberfn() ;
} ;
cExampleClass.cpp
cExampleClass::cExampleClass()
{
// body
}
cExampleClass::~cExampleClass()
{
// body
}
void cExampleClass::memberfn()
{
// body
}
or in-lined:
cExampleClass.h
class cExampleClass
{
public:
cExampleClass()
{
// body
}
~cExampleClass()
{
// body
}
void memberfn()
{
// body
}
} ;
In both cases any source file that then uses cExampleClass simply includes the cExampleClass.h, and cExampleClass.cpp (if it exists) is separately compiled and linked.
Note that if the class includes static data member variables, these must be instantiated in a separate compilation unit in order for there to be just one common instance. Example:
cExampleClass.h
class cExampleClass
{
public :
static int staticmember ;
} ;
cExampleClass.cpp
int cExampleClass::staticmember = 0xffff ;
Do you know how to do it manually? If you know, writing a program to do the same thing is straightforward.
There might not be an easy way to do this. The problem is you have to get the #includes right, split the code correctly to different header and cpp files, and if your classes have cyclic dependencies among themselves, you have to deal with them correctly, or better, try to resolve those dependencies to make them non-cyclic.
Best suggestion I can give you: first try to do this manually for two or three classes. Then decide what kind of physical class layout you need. Afterwards, try to write a program. Don't try to write a program unless you fully understand what to do.
By the way, how many classes/files do have?
EDIT: To get a better notion of what a good physical class-to-file layout may be, I suggest to read Large Scale C++ Design from John Lakos. Is a little bit outdated, since it contains nothing about precompiled headers, but still useful.
I suggest writing a script (in your favorite scripting language) to extract the class declarations into their own file. If you're not good at scripting languages, you can always write a C++ program to extract the class declarations.
Another possibility may be to use an IDE with refactoring capabilities or a refactoring application. I have never used these, so I can't advise on their capabilities.