Clarification on classes and scopes in this scenario - c++

I'm currently working with the JUCE Framework to create an audio VST plugin to get to grips and learn, but just want to clarify some basic stuff relating to classes.
in my header file, i have a class EQPLUGProcessor and inside that class i call static juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout();
When i call the function createParameterLayout() in my .cpp i have to write juce::AudioProcessorValueTreeState::ParameterLayout EQPLUGAudioProcessor::createParameterLayout(){}
My question is, why do i have to include the juce::AudioProcessorValueTreeState::ParameterLayout before the actual scope that the function is in ( EQPLUGAudioProcessor)? Surely i should be telling the compiler to look in the EQPLUGAudioProcessor and thats it?
I get that EQPLUGAudioProcessor is the class which its all inside, but still cant seem to understand when, where and why i'd need to clarify the classes that the function comes from again in the .cpp?
Let me know if this requires clarification.

An enclosing namespace or a class does not have to be specified only inside the same namespace or a class:
class store {
class give_me {
// ...
};
static give_me something_cool();
};
Here, the declaration of something_cool() only needs to reference give_me, rather than store::give_me. This is because this declaration appears inside the declaration of its class.
Now that this class is declared, and it's time to define it's class method, everything must be spelled out:
store::give_me store::something_cool()
{
// ...
}
If the class method returned a void instead you'l still have to write something like:
void store::something_cool()
{
// ...
}
You already understand that you can't just write void something_cool() and define this class method. This would only define some unrelated function with this name.
You have to write store::something_cool because this definition no longer appears within the store scope.
Well, the same thing applies not just to class methods but also to inner classes (and also other kinds of symbols that are declared in some enclosing scope). Since give_me is not a class that's declared in global scope, it is an inner class, when in global scope you must reference it as store::give_me.
That's just how C++ works. There are also various complicated rules that define where a scope begins, and ends, with respect to C++'s syntax, that's tangentially related to this. In some cases it is possible to take advantage of these scoping rules and avoding explicit scope references by using an auto declaration with a trailing return type; but how to do that will have to be a different question for some other time.

Related

How does static worked with all class objects using ClassA::m_variable

We recently found issue with our project caused by this error:
namespace sim
{
class ClassA
{
private:
static std::list<uint16_t> m_variable;
}
std::list<uint16_t> ClassA::m_variable;
}
So what happened is that m_variable became static for all instances of ClassA, not just for the particular instance of it. I'm not an expert with C++ so please bear with me if the problem is staring directly at my face, I'm still on the learning phase.
Can someone explain why this happened?
After your comment, you want to understand how to use static members of class.
For normal data members, one instance of the member exists in each and every instance of the class. OTOH a static data member exists only once and is shared among all object instances of the class.
Simply the simple declaration of a static member inside a class definition is only a declaration. Because of the One Definition Rule, that object also needs a definition.
In C++ language, that definition normally occurs outside of the class definition, so the line std::list<uint16_t> ClassA::m_variable; is required.
There are exception to that rule, mainly for static const integral members that can be defined inside the class definition provided you only use their value and not their address (search for One Definition Rule if you want to go further that way). But this is a rather advanced corner case, so if you are a beginner just remember that a static member of a class need a definition outside the class definition.

C++ Declaration of class variables in header or .cpp?

So far, I've been using classes the following way:
GameEngine.h declares the class as follows
class GameEngine {
public:
// Declaration of constructor and public methods
private:
InputManager inputManager;
int a, b, c;
// Declaration of private methods
};
My GameEngine.cpp files then just implement the methods
#include "____.h"
GameEngine::GameEngine() {
}
void GameEngine::run() {
// stuff
}
However, I've recently read that variable declarations are not supposed to be in the header file. In the above example, that would be an inputManager and a, b, c.
Now, I've been searching for where to put the variable declarations, the closest answer I found was this: Variable declaration in a header file
However, I'm not sure if the use of extern would make sense here; I just declare private variables that will only be used in an instance of the class itself. Are my variable declarations in the header files fine? Or should I put them elsewhere? If I should put them in the cpp file, do they go directly under the #include?
Don't confuse a type's members with variables. A class/struct definition is merely describing what constitutes a type, without actually declaring the existence of any variables, anything to be constructed on memory, anything addressable.
In the traditional sense, modern class design practices recommend you pretend they are "black boxes": stuff goes in, they can perform certain tasks, maybe output some other info. We do this with class methods all the time, briefly describing their signature on the .h/.hpp/.hxx file and hiding the implementation details in the .cpp/.cc/.cxx file.
While the same philosophy can be applied to members, the current state of C++, how translation units are compiled individually make this way harder to implement. There's certainly nothing "out of the box" that helps you here. The basic, fundamental problem is that for almost anything to use your class, it kind of needs to know the size in bytes, and this is something constrained by the member fields and the order of declaration. Even if they're private and nothing outside the scope of the type should be able to manipulate them, they still need to briefly know what they are.
If you actually want to hide this information to outsiders, certain idioms such as PImpl and inlined PImpl can help. But I'd recommend you don't go this way unless you're actually:
Writing a library with a semi-stable ABI, even if you make tons of changes.
Need to hide non-portable, platform-specific code.
Need to reduce pre-processor times due to an abundance of includes.
Need to reduce compile times directly impacted by this exposure of information.
What the guideline is actually talking about is to never declare global variables in headers. Any translation unit that takes advantage of your header, even if indirectly, will end up declaring its own global variable as per header instructions. Everything will compile just fine when examined individually, but the linker will complain that you have more than one definition for the same thing (which is a big no-no in C++)
If you need to reserve memory / construct something and bind it to a variable's name, always try to make that happen in the source file(s).
Class member variables must be declared in the class definition, which is usually in a header file. This should be done without any extern keywords, completely normally, like you have been doing so far.
Only variables that are not class members and that need to be declared in a header file should be declared extern.
As a general rule:
Variables that are to be used with many functions in the same class go in the class declaration.
Temporary variables for individual functions go in the functions themselves.
It seems that InputManager inputManager; belongs in the class header.
int a, b, c; is harder to know from here. What are they used for? They look like temporary variables that would be better off in the function(s) they're used in, but I can't say for sure without proper context.
extern has no use here.

Global object of a class with private constructor

Is it possible to somehow declare the global scope as a friend of a class?
The problem I am facing is the following:
class Foo
{
Foo() {}
};
Foo foo; //error: 'Foo::Foo()' is private
So, what I want is to be able to declare an object of Foo at the global scope but not anywhere else.
Note that this question is purely out of interest, I'm not trying to solve an actual problem.
No, it's not possible to do that. You can only name specific classes or functions as friends. It's not possible to make a namespace including the global namespace a friend.
I think the reason there isn't a good work around is that when you define a class or function, only one definition is allowed (not considering overloads, which are really different functions). But, you are allowed to open a namespace as many times as you want and append extra stuff into it each time. So, if you allowed access to a particular namespace, anybody who wanted to could type:
namespace TheNamesapceWithAccess
{
// I've got access to it here too as well as
// to the original namespace definition that was
// the only one that was intended to be allowed access.
// And I could define a function here that allows access the private thing
// from outside this namespace. I've just subverted the access restriction
// you intended.
}

Understanding of the objects creation in c++

If i have a class name app and a class name manager. I want to create inside manager class an app class, I've seen two options but I didn't understand the difference.
choice 1:
//.....
class app; //writing this line outside the declaration of the func
class manager{
//..
private:
app *a;
//...
}
or choice 2:
class manager{
//..
private:
app *a;
//..
}
I think you're talking about forward declaration. If so, then read this:
C++ INCLUDE Rule : Use forward declaration when possible
Read also this FAQ:
[39.12] What special considerations are needed when forward declarations are used with member objects?
The class app; outside your class manager { ... } is a forward declaration. It tells the compiler, "app is a class. I'm not going to tell you what it looks like, but trust me, it is."
Think of your compiler as only knowing about this particular file (which I am assuming is a .h file) when it compiles. You have said that your member class includes a pointer to an "app". "What the heck is an app?" the compiler wants to know. Without the forward declaration (or perhaps an #include app.h or something similar), it doesn't know, and will fail to compile. By saying at the top, class app;, it knows that app is a class. That's all it needs to know to allocate the space for a pointer to it in your member class.
Look, your "choice 2" isn't valid C++. Who knows what was on your mind... Maybe you wanted to write something like this:
class manager {
//..
private:
class app *a;
//..
}
In this case we define pointer to app class, which is unknown here. This can be used instead of #include "app.h", because all pointers are of the same size and you can define a pointer without defining that app class. Your first example does the same thing, but allows you to omit class word in all subsequent definitions of pointers to it.
The first example includes a forward declaration of the class app so that you can declare pointers to it in later code. The second example doesn't mention app at all before you attempt to use it, so the compiler will not accept it. The compiler needs to know what the name app refers to before you can use it to declare additional things.
Since you're only declaring a pointer, you don't yet need to have a full declaration of app. But in order for your program to fully compile and link, you'll need to define app eventually. Possibly within the same file, or possibly in some other file. But somewhere before you attempt to create an instance of that class or use any of its member variables and functions.

forward declare static function c++

I want to forward declare a static member function of a class in another file. What I WANT to do looks like this:
BigMassiveHeader.h:
class foo
{
static void init_foos();
}
Main.cpp:
class foo;
void foo::init_foos();
int main(char** argv, int argc)
{
foo::init_foos()
}
This fails out with "error C2027: use of undefined type 'foo'"
Is there a way to accomplish what I want to do with out making init_foos a free function, or including BigMassiveHeader.h? (BigMassiveHeader.h is noticeably effecting compile time, and is included everywhere.)
You cannot forward declare members of a class, regardless of whether they are static or not.
You can't forward declare members of your class but you could make a namespace and a function inside of that namespace and forward declare that.
namespace nsfoo
{
void init_foos();
}
Your class if needed could friend this function.
If you have a BigMassiveHeader, you should consider splitting it up into several SmallCompactHeaders. If you want to express that many classes and functions belong together semantically, you can put them in the same namespace. You can always provide a convenience-header that includes all your small headers.
You can't partially declare classes in C++, so either you'll have to put the class's declaration in its own, smaller header, or...
Include BigMassiveHeader.h in your file and use precompiled headers.
The Visual C++ way: http://msdn.microsoft.com/en-us/library/2yzw0wyd%28v=VS.71%29.aspx, or the GCC way: http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html.
I know it's not the point of the question, but if BigMassiveHeader.h is not likely to change much over time, you should take a look at precompiled headers
As a first refactoring, I'd use a free function which calls the static function. It's not like your main method is getting called lots of times, so you won't notice an extra call, and that makes the least change to the existing code.
Of course, you don't actually say what you are trying to do, only what you want to do. If what you are trying to do is get init_foos called once on application start, use static object initialisation for that, rather than calling it in main. If what you are trying to do is get init_foos called after all static objects are created, then it's more complicated.
By static object initialisation, I mean something like having this in a .cpp file which has access to the definition of init_foos. Make it a friend and init_foos private to prevent multiple calls:
struct call_init_foos {
call_init_foos () { foo::init_foos(); }
} call_init_foos_on_startup;
to forward declaration of a single method of a class, you must declare the method as part of the class (as it really is).
for example, in your case, add to main.cpp:
class foo
{
public:
static void init_foos();
}
its not the prettiest, but it will save you having to include the whole header..
No, you need to include the header for that. Sorry.
Use a free function if you must, or split the class.