I'm trying to understand some c++ code I stumbled across on the internet. It was the flex demo from NVIDIA with the awesome new fluid simulation and so I peeked a bit into the code. In there, I've seen something I didn't understand: There was a class called Scene in scene.h. It had no includes, yet it used the CreateRandomConvex function from the helpers.h file. Both of them where only included in the main.cpp but it didn't use either of them.
So my question now is: How can the Scene class access the helpers function without including it? And how does the compiler know where he can get the CreateRandomConvex function from if the Scene class has no includes?
Code:
main:
#include "B.h"
#include "A.h"
int main()
{
}
A.h:(Scene)
#pragma once
class Scene
{
void Init()
{
CreateRandomConvex();
}
};
B.h:(helpers)
#pragma once
void CreateRandomConvex()
{
//calc some stuff
}
#include "A.h" literally means ”insert the contents of the file "A.h" here”.
So when compiling the main file, the compiler sees
void CreateRandomConvex()
{
//calc some stuff
}
class Scene
{
void Init()
{
CreateRandomConvex();
}
};
int main()
{
}
As a side note, having one header depend on another already having been included isn't a very good practice.
To include A.h in a CPP file you must include the file B.h beforehand in that CPP file.
one can argue this is bad practice. But it works.
Related
For a project that I am working on, I need to mock certain classes for testing to test different behaviours of functions. For testing I use gtest. Because I am working on a game, the speed and efficiency of the code is of the essence. Because of this requirement I do not want to mock my classes by using virtual functions, but I want to mock my classes with templates, so the implementation of the classes will be defined at compile time and I do not lose performance at run time. Furthermore, because I want to have the least amount of code bloat in my other header/source files I want to split my files into headers and source files, so that some of the includes can be set in the source file. This approach however comes with a couple of problems.
Because the templated functions are defined in a source file, there will need to be an explicit definition of the classes in the source file. Otherwise these templated functions will throw an 'undefined external symbol' error at compile time. This would not be a problem if I did not have two different projects, one for the game and one for testing, as I can't make an explicit definition of a mock in the test project.
I have tried a couple of solutions, but all of them have drawbacks. I will try to demonstrate what I have done with the following piece of code: (I know and use GMock, but this is an easier example)
//Game project
//Foo.h
<template class Bar>
class Foo
{
public:
Bar bar;
bool ExampleFunction();
}
//Foo.cpp
#include "Foo.h"
<template class Bar>
bool Foo::ExampleFunction()
{
return bar.Func() > 10;
}
//Testing project
//BarMock.h
class BarMock
{
public:
int Func();
int value;
}
//BarMock.cpp
#include "BarMock.h"
Bar::Func()
{
return value;
}
//TestFoo.cpp
#include "Foo.h"
TEST(Tests, TestExample)
{
Foo<BarMock> mocked;
mocked.bar.value = 100;
ASSERT_TRUE(mocked.ExampleFunction());
}
Solution 1: Include cpp file in testing project
This is already error prone, as including a cpp file is usually a no go. But if I only include the cpp file ONCE somewhere in the testing project it will not give me the 'c function already defined' error. This in my opinion is not a solid solution (although it is the solution I am currently using), because if I do need a templated class in 2 locations of my testing project this will (almost) always give an error.
//TestFoo.cpp
#include "Foo.h"
#include "Foo.cpp" // error prone, but does compile
TEST(Tests, TestExample)
{
Foo<BarMock> mocked;
mocked.bar.value = 100;
ASSERT_TRUE(mocked.ExampleFunction());
}
Solution 2: Create definitions in header file
This is less error prone, but comes with some other drawbacks. Like I have stated before I want to keep the bloat to a minimum, but with this solution I will also include all of the headers of the Foo header (say I need in Foo and include foo somewhere, then in somewhere I will also have ).
//Game project
//Foo.h
<template class Bar>
class Foo
{
public:
Bar bar;
bool ExampleFunction()
{
return bar.Func() > 10;
}
}
//Foo.cpp removed
Solution 3: Create virtual functions for mocks
This is my least favourite option, but it should be mentioned. Like I have stated before, this comes with a runtime performance hit and I do not want to change most of my functions to virtual functions. But in this way you will not get errors.
//BarMock.h
class BarMock
{
public:
int Func() override;
int value;
}
//BarMock.cpp
#include "BarMock.h"
Bar::Func() override
{
return value;
}
Which one of these options is the best? Is there any method that I have missed? I would love to hear someone's opinion about this as I could not find a 'good' solution online.
A variation of solution #1 by renaming the files:
Foo.h
#pragma once // or/and header guards
<template class Bar>
class Foo
{
public:
Bar bar;
bool ExampleFunction();
};
Foo.inl (or other extension .inc, .ixx, ...)
#pragma once // or/and header guards
#include "Foo.h"
template <class Bar>
bool Foo<Bar>::ExampleFunction()
{
return bar.Func() > 10;
}
Foo.cpp
#include "Foo.h"
#include "Foo.inc"
#include "Bar.h"
// explicit instantiation
template <> struct Foo<Bar>;
FooTest.cpp
#include "Foo.h"
#include "Foo.inc"
#include "BarMock.h"
// Testing code...
I'm having some troubles where a function isn't returning the right type, because a class isn't defined. I'm using a factory pattern.
The two error messages that I'm getting are:
'return': cannot convert from 'DLA *' to 'Layer *'
and:
'Layer': base class undefined (compiling source file src\Layer.cpp)
and this same error message is repeated for every file that includes Layer.h.
Here is what my class that inherits from Layer looks like (DLA.h):
#pragma once
#ifndef _DLA
#define _DLA
#include "ofMain.h"
#include "ofxGui.h"
#include "Layer.h"
class DLA: public Layer
{
public:
DLA();
void setup();
void update();
void draw();
private:
};
#endif
and here is my Layer class header (Layer.h):
#pragma once
#ifndef _LAYER
#define _LAYER
#include "ofMain.h"
#include "ofxGui.h"
#include "DLA.h"
enum SceneType
{
Scene_None,
Scene_Default,
Scene_DLA,
};
class Layer
{
public:
void setup();
void update();
void draw();
static Layer *CreateSimulation(SceneType Type);
private:
};
#endif
The function which is failing is this one, situated in Layer.cpp:
Layer *Layer::CreateSimulation(SceneType Type)
{
switch (Type)
{
case Scene_None:
default:
return nullptr;
case Scene_DLA:
return new DLA();
}
}
I've tried everything I could find on Stack Overflow that had similar issues to mine but I've seen some people recommend very subtle code indentation to fix this, so I'm really lost as to find where the problem is.
As they stand, your header files induce circular dependency, even though the #pragma once (and other) guards prevent any actual 'infinite recursion'. Let's look at the sequence of code, from the compiler's point-of-view, when compiling the Layer.cpp file (or any other '.cpp' source that has #include "Layer.h" in it).
The compiler encounters #include "Layer.h" (the first time it has done so - the guards won't be 'triggered'), so it duly replaces that line with the contents of the indicated header. In that content, it encounters #include "DLA.h" (we can ignore the other headers included in this discussion, assuming that they aren't relevant to the problem in hand). So, it then duly replaces that line with the contents of the DLA.h header, at which point it will come across this:
#include "Layer.h"
class DLA: public Layer
{
Now, here, when it replaces #include "Layer.h" with the header content, that content will be 'empty' (because of the guards, as it has already included that header once). Thus, when the public Layer code is encountered, it is an error, because that class has not yet been defined, or even declared as a class.
So, if you really insist on having the #include "DLA.h" line in Layer.h, then it must be placed after the definition of the Layer class.
However, a far better way would be to remove #include "DLA.h" from Layer.h, and only place it in source (.cpp) files that actually need it (like Layer.cpp). This would work well:
// Layer.cpp
#include "Layer.h"
#include "DLA.h" // At this point, references to the Layer class in DLA.h will be fine!
//...
Layer *Layer::CreateSimulation(SceneType Type)
{
switch (Type)
{
case Scene_None:
default:
return nullptr;
case Scene_DLA:
return new DLA();
}
}
Feel free to as k for any further clarification and/or explanation.
Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.
I am having much trouble learning to use files for classes in C++. To learn I use Bucky Roberts/The New Boston C++ tutorials, I have tried exactly what he does, but it does not work.
I have the main.cpp and the OtherClass.cpp with the OtherClass.h for header. Every time I try doing OtherClass::OtherClass(){} for the constructor it errors out with "C++ requires a type specifier for all declarations"
Could someone give me an example of how to do C++ class files correctly? Really confused right now.
Thanks!
A simple example of using header files for classes (with the implementation in a separate .cpp file) looks something like this:
Your main.cpp file:
#include "OtherClass.h"
int main()
{
OtherClass otherClass;
//use otherClass here...
}
Next, your OtherClass.h file:
class OtherClass
{
public:
OtherClass();
int someFunction(int parameters);
};
And then finally your OtherClass.cpp file:
#include "OtherClass.h"
OtherClass::OtherClass()
{
//implementation here
}
int OtherClass::someFunction(int parameters)
{
//implemenation here
return 0;
}
The main things to keep in mind:
#include "OtherClass.h" goes in both OtherClass.cpp and main.cpp
make sure you finish constructor and function declarations with ';' not '{}' if you are defining the implementation elsewhere.
make sure you're compiling OtherClass.cpp as well as main.cpp. With MinGW this looks like g++ main.cpp OtherClass.cpp
Your question is a little cryptic to understand, but if I understand correctly you're looking for the `correct' way to create classes with interfaces in the header file. Here is an example of a class that does this:
Scene.h
#pragma once
#include "Window.h"
#include "Entity.h"
class Scene
{
public:
Scene(Window *_window);
~Scene(void);
void render(Entity item);
void render(Entity item, SDL_Rect *clip);
protected:
Window *window;
};
Scene.cpp
#include "Scene.h"
Scene::Scene(Window *_window)
{
window = _window;
}
Scene::~Scene(void)
{
}
void Scene::render(Entity item) {
render(item, NULL);
}
void Scene::render(Entity item, SDL_Rect *clip) {
window->draw( item.getImage(), item.getCoordinates(), clip, item.getAngle() );
}
Notice that the header file includes the headers that it needs to link properly, while the implementation file (.cpp) just includes the header file. The linker should automatically manage all this trouble for you as long as you stick to these semantics.
I hope this helps; if it doesn't, consider rephrasing your question or pasting some code.
Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.