I wrote a program out, which was all in one file, and the methods were forward declared in a header. The program initially worked perfectly when it was in one file. But when I separated the program, I kept getting random occurrences for the destructor of one of the classes which was declared in the header file.
I have a static variable in my header to count the number of objects of a particular class. Whenever I construct the object I increment this variable. Then in my destructor I subtract 1 from that variable, check if it's 0 (meaning it's the last object) and do something. The value seems to be off sometimes, I'm not sure why. I do have random calls in my application but I don't see why that would effect what I have described above, thanks. Any help or insight is appreciated!
[Update]: have a base class, which contains the destructor.. which is implemented in the header, then I have two derived classes, which in their constructor increment the static var.. so what can I do?
What I am trying to do is the following: In my header I have this:
class A {
public:
virtual ~A() {
count --;
if (count == 0) { /* this is the last one, do something */ }
}
class B : public A {
public:
B();
}
Then in Class B I have
B::B() {
count++;
}
Where can I define count so I don't get misleading counts? Thanks.
You must define the constructor in A (all of them) to increment the count.
Note unless you define them the compiler automatically generate the following four methods:
Default Constructor (if no other constructor is defined)
Default Destructor
Copy Constructor
Assignment operator
The following code overrides the compiler defaults so that you should get an accurate count.
class A
{
static int count;
public:
A() // Default constructor.
{
++count;
}
A(A const& copy) // Copy constructor/
{ // Note If you do not define it the compiler
++count; // will automatically do it for you
}
virtual ~A()
{
--count;
if (count == 0)
{ // PLOP
}
}
// A& operator=(A const& copy)
// do not need to override this as object has
// already been created and accounted for.
};
////
In source file:
int A::count = 0;
Where is your static variable defined? Perhaps you are accidentally defining it in the header file, and the inlining is confusing things (and the compiler doesn't catch the multiple definitions, which would be odd, but you never know).
Make sure a class-static variable is defined in exactly one translation unit. You define it like this:
int MyClass::static_var;
This is also the place you put the initializer, if any.
class A {
public:
virtual ~A() {
count --;
if (count == 0) { // this is the last one, do something }
}
protected:
static int count;
};
class B : public A{
public:
B();
};
And then, in one and only one of your source files you need to put the following. It should go in the source file that contains the code for class A.
int A::count(0);
You need to do this, because the header file declared that there was going to be a variable named count, but didn't allocate any storage for it. If you didn't put it in a source file, the linker would complain that it wasn't found.
Can you elaborate what you mean by the "value seems to be off"? Do you get too many constructions? Not enough destructions? If you get too many constructions and not enough destructions, it would not have anything to do with the statics.
Also, what do you mean by a static variable? Do you mean a static member field or an actual static variable ?
If you declare just a static variable in the header (which I doubt that you do), then each C file that includes that header would have a separate instance of that variable (since static before a global variable means that it is limited to that object file).
Related
I am learning C++, and I'm trying to learn more about using the friend keyboard.
However, I am having trouble using nested classes in my Header file.
I know that header files should only be used for declarations but I didnt want to include a cpp file with it so I just used a header file to declare and build.
Anways, I have a main.cpp file that I want strictly to be used for creating objects of classes and accessing its functions.
However, I dont know exactly how to create the FriendFunctionTest function in my header file to where I can access it in my main.cpp source file using the header Class object because I'm trying to understand the "friend" keyword.
Here is my header code:
#ifndef FRIENDKEYWORD_H_
#define FRIENDKEYWORD_H_
using namespace std;
class FriendKeyword
{
public:
FriendKeyword()
{//default constructor setting private variable to 0
friendVar = 0;
}
private:
int friendVar;
//keyword "friend" will allow function to access private members
//of FriendKeyword class
//Also using & in front of object to "reference" the object, if
//using the object itself, a copy of the object will be created
//instead of a "reference" to the object, i.e. the object itself
friend void FriendFunctionTest(FriendKeyword &friendObj);
};
void FriendFunctionTest(FriendKeyword &friendObj)
{//accessing the private member in the FriendKeyword class
friendObj.friendVar = 17;
cout << friendObj.friendVar << endl;
}
#endif /* FRIENDKEYWORD_H_ */
In my main.cpp file, I wanted to do something like this:
FriendKeyword keyObj1;
FriendKeyword keyObj2;
keyObj1.FriendFunctionTest(keyObj2);
But obviously its not going to work since the main.cpp cant find the FriendFunctionTest function in the header file.
How do I fix this issue?
And I apologize again, I'm just trying to learn C++ online.
The friend keyword is only used to specify if a function or other class can have access to the private members of that class. You have no need for class inheritance or nesting because FriendFunctionTest is a global function. Global functions do not require any class prefixes when invoked.
Source for friend: http://msdn.microsoft.com/en-us/library/465sdshe(v=vs.80).aspx
You're really talking about several completely different things here. Here are examples for two of them:
1) "Friends":
http://www.learncpp.com/cpp-tutorial/813-friend-functions-and-classes/
// Class declaration
class Accumulator {
private:
int m_nValue;
public:
Accumulator() { m_nValue = 0; }
void Add(int nValue) { m_nValue += nValue; }
// Make the Reset() function a friend of this class
friend void Reset(Accumulator &cAccumulator);
};
// Reset() is now a friend of the Accumulator class
void Reset(Accumulator &cAccumulator)
{
// And can access the private data of Accumulator objects
cAccumulator.m_nValue = 0;
}
2) "Nested classes":
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr061.htm
A friend is not a member. Here is a good example of how "friend" is used in practice.
namespace Bar {
class Foo {
public:
// whatever...
friend void swap(Foo &left, Foo &right); // Declare that the non-member function
// swap has access to private section.
private:
Obj1 o1;
Obj2 o2;
};
void swap(Foo &left, Foo &right) {
std::swap(left.o1, right.o1);
std::swap(left.o2, right.o2);
}
} // end namespace Bar
We have declared a function for swapping Foo's that is more efficient than std::swap would be, assuming that classes Obj1 and Obj2 have efficient move-semantics. (Darn it, you are quick with that green check mark! :))
It is useful to know that because the swap routine is parameterized by a Foo object (two in this case) and is declared in the same namespace as Foo, it becomes part of Foo's public interface, even though it is not a member. The mechanism is called "argument-dependent lookup" (ADL).
Reading code from other posts, I'm seeing something like this.
struct Foo {
Foo() : mem(0) {}
int mem;
};
What does mem(0) {} does in this case, especially regarding the curly brackets? I have never seen this before and have no idea where else I would find out about this. I know that mem(0), would intialize mem to 0, but why the {}?
Thanks.
Since Foo() is the class' constructor, it must have a body, even if the member variable mem is initialized outside of it.
That's why, in your example, the constructor has an empty body:
Foo() : mem(0)
{
// 'mem' is already initialized, but a body is still required.
}
It defines the constructor of the class. The part after the colon is the initialization list, in which the mem member is initialized to zero using a constructor call.
Compare:
int a(0);
int b = 0;
These two do the same, but the former is more in line with how object construction typically looks in C++.
int c++ you can define your method implementation in .h file
class MyClass
{
public:
MyClass(){
.....
}
void doSomething(){
.....
}
~MyClass(){
.....
}
};
Usually it used in templates implementation. Also you could use this method of class declaration in case you would like to avoid libraries linking and you prefer to give to user all your code so he can include your file without linking any lib file to his project.
I think my problem is best described in code:
#include <stdio.h>
struct Foo;
extern Foo globalFoo;
struct Foo {
Foo() {
printf("Foo::Foo()\n");
}
void add() {
printf("Foo::add()\n");
}
static int addToGlobal() {
printf("Foo::addToGlobal() START\n");
globalFoo.add();
printf("Foo::addToGlobal() END\n");
return 0;
}
};
Foo globalFoo;
int dummy = Foo::addToGlobal();
int main() {
printf("main()\n");
return 0;
}
The above prints (with gcc 4.4.3):
Foo::Foo()
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
main()
This is what I expect, and seems logical.
However, when I swap the following lines:
Foo globalFoo;
int dummy = Foo::addToGlobal();
into this:
int dummy = Foo::addToGlobal();
Foo globalFoo;
the program outputs the following:
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
Foo::Foo()
main()
It seems instance methods of Foo are being called using an instance which has not yet been constructed! Something as simple as moving the declaration of a variable in the global scope is affecting the behaviour of the program, and that leads me to believe (1) the order of initialization of globals is not defined and (2) the order of initialization of globals ignores all dependencies. Is this correct? Is it possible to make sure the constructor of Foo is called before initializing dummy?
The problem I am trying to solve is filling a repository of items (a static instance of Foo) statically. In my current attempt, I am using a macro which (among other things) creates a global variable (in an anonymous namespace to avoid name clashing) whose initialization triggers the static initialization. Perhaps I'm tackling my problem from the wrong angle? Is there a better alternative(s)? Thanks.
(1) the order of initialization of globals is not defined
Global variables in a single translation unit (source file) are initialized in the order in which they are defined.
The order of initialization of global variables in different translation units is unspecified.
(2) the order of initialization of globals ignores all dependencies
Right.
Is it possible to make sure the constructor of Foo is called before initializing dummy?
Yes, if globalFoo is defined before dummy and they are in the same translation unit.
One option would be to have a static pointer to the global instance; such a pointer will be initialized to null before any dynamic initialization takes place; addToGlobal can then test whether the pointer is null; if it is, then it is the first time the global is being used and addToGlobal can create the global Foo.
On the order of initialization, read the answer here.
On how to solve the initialization issue, you can push the global to be a static local variable in a function. There standard guarantees that the static local variable will be initialized in the first call to the function:
class Foo {
public:
static Foo& singleton() {
static Foo instance;
return instance;
}
};
Then your other global variables would access the variable as:
Foo::singleton().add();
Note that this is not generally considered as a good design, and also that even if this solves the initialization issues, it does not solve the order of finalization, so you should be careful not to access the singleton after it has been destroyed.
C++ lacks anything like Ada's pragma elaborate, so you can't make any assumptions whatsoever about the order initilizations will happen in. Sorry. It sucks, but that's the design.
The most reliable way to provide correct init order for globals...
1) Init order depends on object files order passed to linker. Straight or reverse -not matter. You may create test application to detect it.
2) Use appropriate utilities( nm for example ) to discover imports & exports for each object file that contains globals.
3) Build the dependencies graph, sort object files and build required order for correct linking. Resolve cycles manually if exists.
I use such procedure in my makefiles on Linux. It works...
You're correct, initialization of globals between translation units is undefined. It is possible to get around this using the singleton pattern. However, be warned that this design pattern is often misused. Also be warned that order or destruction of globals is also undefined, in case you have dependencies in the destructors.
How about having the static global variable be a pointer initialized to nullptr. Then before another global object tries to use the object, check for its creation and create if needed. This worked for me for creating a global registry of class creators where one could add new classes without changing the file that handled the registry.
i.e.
class Factory {
static map<string, Creator*>* theTable;
static void register1(const string& string, Creator* creator);
...
};
...
map<string, Creator*>* Factory::theTable= nullptr;
void Factory::register1(const string& theName, Creator* creator) {
if (!theTable) theTable=new map<string, Creator*>;
(*theTable)[theName]=creator;
}
This compiled and worked with VC++ in Visual Studio 2015.
I had tried using before this
class Factory {
public:
static map<string, Creator*> theTable;
static map<string, Creator*>& getTable();
static void register1(const string& string, Creator* creator);
}
map<string, Creator*> Factory::theTable;
map<string, Creator*>& Factory::getTable() {
return theTable;
}
void Factory::register1(const string& theString, Creator* creator) {
getTable()[theString]=creator; // fails if executed before theTable is created
}
but I still had exceptions thrown when theTable was not created before trying to insert an entry into the map, which can happen if the registration of the class is handled in a separate compilation unit from the factory logic.
Global variables in a single translation unit (source file) are initialized in the order in which they are defined.
It is important to add the note to this rule that the mere declaration does not define the order:
extern Foo globalFoo; // or just a ref that is defined at a single place
extern Foo & globalFooRef;
or as a static member
struct Global
{
static Foo globalFoo; // or just a ref that is defined at a single place
static Foo & globalFooRef;
};
I was wondering if there is a way to put objects of a class in a header?
For example:
class MyClass {
} object;
If I made an object there and then include the header in more than one source file, I get an error of multiply defined symbols found. I am new so don't understand fully everything.
Also, I want to do something like object.function() inside of a different function which is a member of a different class how can I do that?
Assuming you want a single object, in the header file just declare the object:
extern blabla object;
and then in one source file define it:
blabla object;
As for calling a method on an object from a different class, that is perfectly fine as long as the method is public.
class foo
{
public:
void public_method();
private:
void private_method();
};
void some_other_class::method(foo &f)
{
f.public_method(); // this is fine
f.private_method(); // this is not okay, private_method can only be called from
// within foo
}
There's also a third visibility (protected), which comes into play once you start dealing with inheritance.
You can find ways to do it (see the other answers), but just don't do it. As you said, you are new to C++, so better learn the good practices, and when you need global objects - create them in the source (cpp) file.
Besides it, try to avoid using global objects at all, and define your objects inside the classes or functions.
It's not a good practice to put definitions in header files as this would result to the error you encountered. Although there are ways to get around this (extern, header guard), it should be avoided as much as possible. Just remember, put declarations in header files, definitions in source files.
About your second question note you can also call a static method using the :: operator and the class name (without an instance) :
void AnOtherClass::method()
{
TheFirstClass::static_method();
}
You could also make a use of the singleton pattern, if that fits your need in this case.
For your second question. You can always make a class object as a (private) member variable of the class you want to call object.function() from.
For example:
// File a.h, includeguards etc. left out for clarity
class A {
public:
void func();
};
// File b.h
#include "a.h"
class B {
public:
void func();
private:
A object;
};
// File b.c
#include "b.h"
void B::func()
{
object.func();
}
Hope that helps.
Sorry if this question seems trivial to many here.
In a C++ code there is something as below:
class Foo
{
public:
static int bands;
...
...
private:
...
...
}//class definition ends
int Foo::bands; //Note: here its not initialized to any value!
Why is the above statement needed again when 'bands' is once declared inside the class as static?
Also can a static variable be declared as a private member variable in any class?
C++ notes a distinction between declaring and defining. bands is declared within the class, but not defined.
A non-static data member would be defined when you define an object of that type, but since a static member is not a part of any one specific object, it needs it's own definition.
a) It's needed because that's the way the languge is designed.
b) Static variables are initialized by their default constructor, or to zero for built-in types.
c) Yes, they can be (and usually are) private.
Take a look at this question.
It has to do with obj files, how they are used, and how memory addresses for globally scoped variables are ultimately discovered through the linking process. Object files contain the addresses of all global data and functions defined in the corresponding cpp. They layout some memory in a relative fashion to tell the liker where in that file these global vars/funcs can be found. So for example
function doFoo can be found 0 bytes from beginning of this file
int foo::bands can be found 12 bytes from beginning of this file
etc
Its almost easier to think about if you've done straight C before. In a pure C world you would do things in a more traditional modular programming sense. Your module would be defined with a header and a cpp. The header would define a "public" variable like below, using the extern keyword, then instantiate it in the cpp.
foo.h
extern int bands;
foo.cpp
#include "foo.h"
int bands;
foo.obj:
int bands can be found 0 bytes from the beginning of this file
The "extern" keyword states that this name is valid and its address will get resolved at link time. Everyone that included "foo.h" and wanted to use the "bands" global variable had could now use it. At link time, the linker would figure out that bands existed in the foo.obj. If you forgot to put "int bands" in foo.obj, you'd get a linker error, and have to go resolve it.
In C++ using static in a class declaration i similar. You are telling the users that there exists this thing called "foo::bands" and where it will live will get resolved at link time. Later down the line, the linker sees that in foo.obj, foo::bands exists, and all references to foo::bands can be resolved.
My understanding is that you would only need to declare Foo::bands if you planned on using it prior to ever creating an instance of your class. Basically, when you declare a static in a C++ class then only one copy of that variable exists for all instances of that class. However, you can't normally access Foo::bands until an instance of the class is declared.
For example:
Pointers to Members
#include <iostream>
using namespace std;
class X {
public:
int a;
void f(int b) {
cout << "The value of b is "<< b << endl;
}
};
int main() {
// declare pointer to data member
int X::*ptiptr = &X::a;
// declare a pointer to member function
void (X::* ptfptr) (int) = &X::f;
// create an object of class type X
X xobject;
// initialize data member
xobject.*ptiptr = 10;
cout << "The value of a is " << xobject.*ptiptr << endl;
// call member function
(xobject.*ptfptr) (20);
}