Using Extern variables from C header files with C++ - c++

I have a library that is written for me in C. In the library there is a variable that I need to use
In foo.h (which is in C)
extern mystruct foobar;
In bar.h (which is in C++)
I have the following class.
#include foo.h
class myfoo {
private:
mystruct foobar;
}
What I would like to know is if I create an array of myfoo, will each instance of foobar be referencing the same variable, or will each instance be its own unique instantiation of the myfoo that independent from the other myfoo foobars?

Here’s the deal: you are not using foo.h’s foobar variable in bar.h (this is particularly true because foo.h only declares foobar, a definition would have to be in an implementation file). Rather, you are redeclaring a variable with the same name and type in the scope of the class.
With that, all the normal rules for an instance member variable apply. In particular, every instance of myfoo will have its own instance of foobar.
If you removed the declaration from foo.h nothing would change: the declaration is completely irrelevant for your bar.h file.

The foobar member inside the class definition of myfoo is defined at a different scope from the foobar at global scope. The are different variables, unrelated to each other, except that they are of the same type, and happen to have the same name (although at different scopes).
If you create an array of myfoo objects, each one will have an instance of mystruct. All of those instances will be separate from the one declared in the global scope.

What I would like to know is if I create an array of myfoo, will each
instance of foobar be referencing the same variable, or will each
instance be its own unique instantiation of the myfoo that independent
from the other myfoo foobars?
if you do this:
#include foo.h
class myfoo
{
private:
mystruct foobar;
};
void func()
{
myfoo f[3];
// ...
}
you create 3 different myfoo objects, each with its own foobar instance.
if you change the myfoo declaration as follows:
#include foo.h
class myfoo
{
private:
static mystruct foobar;
};
// this extra declaration is required for
// static member variables
mystruct myfoo::foobar;
void func()
{
myfoo f[3];
// ...
}
then the three instances of myfoo will share their single instance of foobar.
NOTE:
The class myfoo declaration may be in either a '.h' or a '.cpp' file.
The mystruct myfoo::foobar; declaration may only appear once, so it normally has to be in a '.cpp' file (or '.cc' or whatever you use).

Related

Why does the Qt tutorial build the header class like this? [duplicate]

Is some one able to explain why header files have something like this?
class foo; // This here?
class bar
{
bar();
};
Do you need an include statement when using this?
Thanks.
The first class foo; is called a forward declaration of the class foo. It simply lets the compiler know that it exists and that it names a class. This makes foo what is called an "incomplete type" (unless the full declaration of foo has already been seen). With an incomplete type, you can declare pointers of that type, but you cannot allocate instances of that type or do anything that requires knowing its size or members.
Such forward declarations are frequently used when two types each may have pointers to each other, in which case both need to be able to express the notion of a pointer to the other type, and so you would have a circular dependency without such a thing. This is needed mostly because C++ uses a single pass mechanism for resolving types; in Java, you can have circular dependencies without forward declarations, because Java uses multiple passes. You may also see forward declarations where the author is under the misguided impression that using forward declarations instead of including the required header reduces compile time; that, of course, is not the case, because you need to include the full declaration (i.e. the header), anyway, and if preprocessor guards are used, then there is basically no difference in compile time.
To answer your question on whether you need the include or not... assuming you only need a partial type, then your header does not need to directly include the header for the type that has been forward declared; however, whoever makes use of your header, when they use your type will need to include the header for the forward declared type, and so you might as well just include the other header.
That's a forward declaration. You need it for example if class bar has a pointer to a foo object, but you don't want to include the whole definition of the foo object immediately.
this is a forward declaration of the class.
In my experience, this is typically done when you have a circular dependency.. for example
in foo.h
--------
#include "bar.h"
class foo
{
public:
foo(bar *bar);
private:
foo *m_foo;
};
and in bar.h
------------
class foo;
class bar
{
public:
void methodFooWillCall();
protected:
std::list<foo *> myFoos;
}
Just curious, why do we need the term forward declaration at all? Isn't a forward declaration simply a declaration (as opposed to a definition)?
class X; // declaration
class X // definition
{
int member;
void function();
};
That's a forward declaration. Consider the following example:
class foo; // you likely need this for the code beneath to compile
class bar {
void smth( foo& );
};
If you haven't included the definition of class foo in such a way that the compiler sees it before compiling the definition of class bar the code will not compile (the compiler will say it doesn't know what foo means) unless you have the forward declaration.
It's a forwards declaration of the class 'foo'. It allows you to declare pointers and references to the class, but not use it (eg. call members or determine its size), because it's not yet defined! It must later be followed up with a full, normal declaration (class foo { ... };).
It's useful for things like declaring two classes which hold pointers to each other, which otherwise would be impossible to set up.
This is called forward declaration. The body of the class foo would be defined at a later part of the file. Forward declaration is done to get around cyclic dependencies: The definition of class Bar requires class Foo and vice versa.
class Bar
{
Foo * foo;
};
class Foo
{
Bar * bar;
};
As you can see, Bar has a reference to Foo and vice versa. If you try to compile this, the compiler will complaint saying that it doesn't know anything about Foo. The solution is to forward declare the class Foo above the Bar (just like you declare the prototype of a function above the main and define its body later).
class Foo; //Tells the compiler that there is a class Foo coming down the line.
class Bar
{
Foo * foo;
};
class Foo
{
Bar * bar;
};
This is called a forward declaration. It is used to make your code aware that the class foo exists. This in turn can be used by the class bar.
It's commonly used to solve circular includes problems. Take this for example
//a.h
#include "b.h"
class A
{
void useB(B obj);
}
and
// b.h
#include "a.h"
class B
{
void useA(A obj);
}
This causes a circular include problem, because a.h includes b.h which in turns includes a.h, to infinity. You can solve this problem by making a forward declaration of each class in each header, like so :
//a.h
class B;
class A
{
void useB(B obj);
}
// b.h
class A;
class B
{
void useA(A obj);
}
Note : Very often when you have a circular include problem, this is indicative of a conception/modelling problem. You should probably ask yourself if your classes are well defined before trying to solve your problem with forward declarations.
Try to think of writing this:
file bar.h:
#include "bar.h"
class Foo
{
Bar* bar_ptr;
}
file foo.h:
#include "foo.h"
class Bar
{
Foo* foo_ptr;
}
This won't work, first due to infinite #include chain, then if you get rid of one of the includes, either Foo won't know what Bar is, or Bar won't know what Foo is.
Try this instead:
class Bar;
class Foo
{
Bar* bar_ptr;
};
file foo.h:
class Foo;
class Bar
{
Foo* foo_ptr;
};

Declare class object globally but without parameters

So here's my situation: I have a class foo residing in foo.cpp with header file foo.h included in my main.cpp. I need to be able to declare a foo object as a global variable in main.cpp so that it is available to all functions within main.cpp without having to pass a reference to it every time. The problem is, foo's constructor requires a variable which isn't retrieved from the user until halfway through the main function in main.cpp. I thought I could do this this way:
static foo myFoo;
As a global variable above the main function, then after the necessary data is retrieved from the user (let's call it "variable"), I could call:
myFoo = new foo(variable);
I'm getting an error however with this:
error: no matching function for call to ‘foo::foo()’
referencing the line with static foo myFoo;
So it's basically saying that I'm trying to declare an instance of foo with a constructor taking zero arguments, when there is none.
So my question is: Is there a way to declare a label myFoo out of foo as a global variable so that the program compiles, and then later it can actually be instantiated using the constructor with a variable passed?
I know I could just do something like this:
string temp = "";
static foo myFoo(temp);
above main() and then have some function defined where I could do
myFoo.setVar(variable);
when I needed to. To me this is very ugly and necessitates the inclusion of the function setVar which has no tangible purpose other than to circumvent this very issue. Thoughts?
One option you have is to make your static instance a pointer:
static foo *myFoo = NULL;
// Later...
myFoo = new foo(variable);
Or you may want to use a default constructor and make an Init method instead.
static foo myFoo;
// Later...
myFoo.Init( variable );
When you're exposing a variable, you don't define it as static. Remove the static keyword and use extern in the header's declaration.
static foo myFoo;
That line will create a new object of type foo during the static initialization if your program. It will call the default constructor (if you don't define one, the compiler will create one for you in certain situations - you haven't posted enough code to know if that is the case here). Note that if it is defined in a header file, you will need to extern it.
Attempting to set myFoo to a pointer using
myFoo = new foo(variable);
will not compile. new foo(...) returns a foo*, not a foo. If you want it to be a pointer, you need to declare your static variable as
static foo* myFoo;
If you want it to be an object and want to set it to something other than the default, you can implement a copy-assignment operator and do something like this
foo newFoo(variable);
myFoo = newFoo;
Or provide an initialization function to change the construction values after the fact (prefer the copy-assignment in most cases as it will be less prone to errors).
I believe you might not be defining the default constructor. Once you define a constructor, the default constructor is not automatically defined. This works for me:
myclass.hpp:
#ifndef _MYCLASS_
#define _MYCLASS_
class myClass
{
public:
int I;
myClass(int i);
myClass();
};
#endif
myclass.cpp:
#include "myclass.hpp"
myClass::myClass(int i) : I(i) {};
myClass::myClass() : I(0) {};
main.cpp:
#include "myclass.hpp"
myClass myGlobalClassObject;
int main()
{
myClass myLocalClassObject(1);
myGlobalClassObject.I = 2;
return 0;
}
You are indicating that you foo object cannot be properly instantiated until halfway down the main function. This sounds like you will have an object in an inconsistent state for the first half of your main function. Very dangerous.
Anyway, there is a couple of ways to get to it:
1) If you want to create a static foo object you can use a default value for your constructor:
class foo {
public:
foo( type variable = default ) {
...
}
...
You can now declare your foo object as a global in main
foo myFoo;
and myFoo's variable will be initialised with “default”
or, without a default:
class foo {
public:
foo( type variable ) {
...
}
...
Declare your foo object as a global in main
foo myFoo(default);
Depending whether “default” makes sense in your application you can now use your myFoo object in main.cpp's functions. If “default” does not make sense you will have to add a test function before you use myFoo.
Of course you also need another member function to be able to set “variable” to your user input (something like set_variable(variable); )
2) Use a pointer. Declare a global foo * myFoo in main.cpp and test if the pointer is NULL before using it.
Now your constructor does not need a default value, it still needs the variable:
foo::foo(type variable) { ... }
You initialise your myFoo object by using: myFoo = new foo(user_input);
You can test the myFoo pointer to NULL as all uninitialised global variables are set to 0 by the startup code.
(As an aside: you do realise of course that globals are frowned upon and as such should be avoided)
Good luck

What is the best way to define a struct which is only needed by a certain class?

Given the following simplified class which contains a vector of MyStruct objects, where should I define MyStruct assuming that it's only being used inside of Foo and should not be seen or used from outside?
class Foo
{
std::vector<MyStruct> array;
};
Two possibilities I've come across are putting the definition of MyStruct right inside of Foo or using an anonymous namespace.
If array is in any way a public part of Foo interface, declare MyStruct like this:
class Foo
{
public:
struct MyStruct { /* stuff */ };
/* ... */
};
Otherwise: declare it in the private section of Foo.
In this case, you have to define it in Foo, since it has to
be completely defined before you use it to instantiate
std::vector. Otherwise, it depends; I'd tend to define it in
a private namespace: an unnamed namespace in the implementation
file if all of the functions are in a single source file,
otherwise in a private, implementation header file in a private
namespace (e.g. FooPrivate) if they aren't.
If you do not want it to be used outside Foo, then the best way is to declare it in the private section of Foo
class Foo
{
struct My_Struct;
}

Where to place Structs and Enums in C++ class + final constants

I have started reading C++ and I have a question about classes and member variables of type Enum and Struct. Where should I declare Enums/Structs so that I can use them as member variables when I separate header and implementation file? And also, how can I make a final member variable in a C++ class? I am just getting compilation error when adding const int myTest as a member variable, where should I initialize them?
The header file is like a person saying 'I can do this, that and the other' - so put declarations into it - enums, structs, class declarations, constants, ...
The implementation file is like a person saying 'I can do this and this is how I can do it' - it produces a recipe - Actual machine code for the CPU to crunch.
const says - do not change me. To intialise in a class you need:
class X
{
private:
const int y;
public:
X() : y(5) {}
};
for example. If you are learning about C++ const is a very useful tool to prevent you making a multitude of errors.
the simplest solution is to simple declare the enums & structs directly before the class they are a member of:
struct Gizmo
{
int n_;
};
class Foo
{
public:
Gizmo gizmo_;
};
If Gizmo is logically coupled to Foo (eg, if you would never use a Gizmo outside the context of using a Foo), it might also make sense to make Gizmo a nested class:
class Foo
{
public:
struct Gizmo
{
int n_;
};
Gizmo gizmo_;
};
If you want to instantiate a Gizmo declared this way, you can resolve the scope yourself:
Foo::Gizmo gizmo;
Finally, if Gizmo and Foo are not logically coupled, and you might use Gizmos all over the place without needing a Foo, then it probably belongs in its own header file.
gizmo.h
struct Gizmo
{
int n_;
};
foo.h
#include "gizmo.h"
class Foo
{
public:
Gizmo gizmo_;
};
Where should I declare Enums/Structs so that I can use them as member variables when I separate header and implementation file?
You must declare them before their use, that is. before the declaration of the member in the class of their type. Either:
you define them in their own header file and #include that file in your class' header file (before the declaration of your class)
or you define them just before your class
or you define them in your class before the members
I am just getting compilation error when adding const int myTest as a member variable, where should I initialize them?
In the constructor, using initializers. Ie.:
Clazz::Clazz() : my_const_var(0) { ... }
If you're going to add an enum or struct as a member variable of the class, the definition of the enum or struct must be complete before you declare the member. This can either be inside the class, outside of the class but coming before it in the .h header, or in a different .h header that is included before or within the current one.
There shouldn't be any problem declaring a member variable as const, but it places a restriction on how it must be initialized. You must do it in the initializer list of the constructor.
MyClass::MyClass() : myTest(value)
{
}

class foo; in header file

Is some one able to explain why header files have something like this?
class foo; // This here?
class bar
{
bar();
};
Do you need an include statement when using this?
Thanks.
The first class foo; is called a forward declaration of the class foo. It simply lets the compiler know that it exists and that it names a class. This makes foo what is called an "incomplete type" (unless the full declaration of foo has already been seen). With an incomplete type, you can declare pointers of that type, but you cannot allocate instances of that type or do anything that requires knowing its size or members.
Such forward declarations are frequently used when two types each may have pointers to each other, in which case both need to be able to express the notion of a pointer to the other type, and so you would have a circular dependency without such a thing. This is needed mostly because C++ uses a single pass mechanism for resolving types; in Java, you can have circular dependencies without forward declarations, because Java uses multiple passes. You may also see forward declarations where the author is under the misguided impression that using forward declarations instead of including the required header reduces compile time; that, of course, is not the case, because you need to include the full declaration (i.e. the header), anyway, and if preprocessor guards are used, then there is basically no difference in compile time.
To answer your question on whether you need the include or not... assuming you only need a partial type, then your header does not need to directly include the header for the type that has been forward declared; however, whoever makes use of your header, when they use your type will need to include the header for the forward declared type, and so you might as well just include the other header.
That's a forward declaration. You need it for example if class bar has a pointer to a foo object, but you don't want to include the whole definition of the foo object immediately.
this is a forward declaration of the class.
In my experience, this is typically done when you have a circular dependency.. for example
in foo.h
--------
#include "bar.h"
class foo
{
public:
foo(bar *bar);
private:
foo *m_foo;
};
and in bar.h
------------
class foo;
class bar
{
public:
void methodFooWillCall();
protected:
std::list<foo *> myFoos;
}
Just curious, why do we need the term forward declaration at all? Isn't a forward declaration simply a declaration (as opposed to a definition)?
class X; // declaration
class X // definition
{
int member;
void function();
};
That's a forward declaration. Consider the following example:
class foo; // you likely need this for the code beneath to compile
class bar {
void smth( foo& );
};
If you haven't included the definition of class foo in such a way that the compiler sees it before compiling the definition of class bar the code will not compile (the compiler will say it doesn't know what foo means) unless you have the forward declaration.
It's a forwards declaration of the class 'foo'. It allows you to declare pointers and references to the class, but not use it (eg. call members or determine its size), because it's not yet defined! It must later be followed up with a full, normal declaration (class foo { ... };).
It's useful for things like declaring two classes which hold pointers to each other, which otherwise would be impossible to set up.
This is called forward declaration. The body of the class foo would be defined at a later part of the file. Forward declaration is done to get around cyclic dependencies: The definition of class Bar requires class Foo and vice versa.
class Bar
{
Foo * foo;
};
class Foo
{
Bar * bar;
};
As you can see, Bar has a reference to Foo and vice versa. If you try to compile this, the compiler will complaint saying that it doesn't know anything about Foo. The solution is to forward declare the class Foo above the Bar (just like you declare the prototype of a function above the main and define its body later).
class Foo; //Tells the compiler that there is a class Foo coming down the line.
class Bar
{
Foo * foo;
};
class Foo
{
Bar * bar;
};
This is called a forward declaration. It is used to make your code aware that the class foo exists. This in turn can be used by the class bar.
It's commonly used to solve circular includes problems. Take this for example
//a.h
#include "b.h"
class A
{
void useB(B obj);
}
and
// b.h
#include "a.h"
class B
{
void useA(A obj);
}
This causes a circular include problem, because a.h includes b.h which in turns includes a.h, to infinity. You can solve this problem by making a forward declaration of each class in each header, like so :
//a.h
class B;
class A
{
void useB(B obj);
}
// b.h
class A;
class B
{
void useA(A obj);
}
Note : Very often when you have a circular include problem, this is indicative of a conception/modelling problem. You should probably ask yourself if your classes are well defined before trying to solve your problem with forward declarations.
Try to think of writing this:
file bar.h:
#include "bar.h"
class Foo
{
Bar* bar_ptr;
}
file foo.h:
#include "foo.h"
class Bar
{
Foo* foo_ptr;
}
This won't work, first due to infinite #include chain, then if you get rid of one of the includes, either Foo won't know what Bar is, or Bar won't know what Foo is.
Try this instead:
class Bar;
class Foo
{
Bar* bar_ptr;
};
file foo.h:
class Foo;
class Bar
{
Foo* foo_ptr;
};