Reputation: 39
Let's say I have a main.cpp, class1.cpp, class1.h, as well as other header files that won't be specified:
class1.h
#pragma once
class Class1 {
public:
Class1(int val);
void pubFunc();
private:
int val1;
void privFunc();
}
class1.cpp
#include "class1.h"
Class1::Class1(int val) {
val1 = val;
}
void Class1:pubFunc() {
if (val1 > 0)
privFunc();
}
main.cpp
#include "class1.h"
#include "anotherclass.h"
AnotherClass ac;
int main() {
Class1 c1(10);
c1.pubFunc();
}
Class1::privFunc() {
ac.doSomething;
}
I want Class1::pubFunc()
to essentially trigger another function that can make use of AnotherClass
, without including its header inside class1.cpp. This is the method that I thought of, but it feels disorganized, and I'm not too keen on putting the class instances outside of main()
. The only other way I can think of doing this making Class1::pubFunc()
return a string
, which maps to a function, but I don't know if that's any better.
Upvotes: 0
Views: 197
Reputation: 1
Misconception. A class in C++ does not need to have its own *.cpp
file and there are pragmatical reasons to avoid having lots of tiny *.cpp
files (and prefer instead having less *.cpp
files, each defining several related classes and functions, so being slightly bigger).
A given translation unit (e.g. the *.cpp
files and all the header files it is #include
-ing) can (and usually does) define and declare several class
-es and functions.
In practice, you code in C++ by using several standard containers or other standard C++ facilities provided by standard C++ headers, such as smart pointers from <memory>
, strings from <string>
, vectors from <vector>
, sorting functions from <algorithm>
and so on. The powerful C++ standard library is one of the reasons to code in C++ (instead of C, for instance). So you would #include
perhaps several standard headers like <vector>
or <map>
. Standard headers are quite complex: on my Linux machine, #include <vector>
generally expands to more than ten thousand of included lines (and that is one of the reasons why C++ code compiles slowly). So it is unwise (but possible) to have many small C++ files of a hundred lines each which are including some standard header, because a small yourcode.cpp
file containing #include <vector>
and two hundreds lines of your C++ code is expanded to much more: the compiler parses about 10000 lines of code (LOC) from <vector>
and 200LOC of your code, so 10200 LOC in total.
BTW, you can ask your compiler to give the preprocessed form of your translation unit (with GCC, using g++ -C -E yourcode.cpp > yourcode.ii
) and look (with an editor or a pager) inside that yourcode.ii
.
(your example is not genuine C++11 code; in practice, it should often use standard containers and some other features -smart pointers, threads, standard algorithms...- of the rich C++ standard library, but it does not)
So I recommend to have your *.cpp
containing at least a thousand or two of your C++ source code lines, and of course they could define several of your related classes (and functions). In some cases, a single C++ class
might be implemented in several C++ files (because that class has a lot of methods).
BTW, in your C++ classes, a lot of small functions (including member functions) are inlined and you'll define them in some of your header file.
I recommend studying the source code of several C++ free software projects for inspiration. You'll find many of them on github or elsewhere.
Upvotes: 2
Reputation: 283634
Your question is a consequence of an earlier questionable decision -- to use a global variable to share an instance of AnotherClass
between main()
and Class1
.
If you break that dependency, perhaps by using a callback, or an interface, then your need to scatter Class1
member function definitions across multiple compilation units will disappear as well.
Here's one way you might cure the dependency:
class1.h
#include <functional>
class Class1
{
public:
Class1(int val, std::function<void(void)> callback);
void pubFunc(void);
private:
std::function<void(void)> do_the_thing;
int val1;
};
class1.cpp
#include "class1.h"
Class1::Class1(int val, std::function<void(void)> callback)
: val1(val), do_the_thing(std::move(callback))
{
}
void Class1:pubFunc(void)
{
if (val1 > 0)
do_the_thing();
}
main.cpp
#include "class1.h"
#include "anotherclass.h"
int main(void)
{
AnotherClass ac;
Class1 c1(10, std::bind(&AnotherClass::doSomething, ac));
// can also write as [](){ ac.doSomething(); }
c1.pubFunc();
}
Upvotes: 2