Programming FAQ

– How do I call a method from another class?
– How do I solve linking errors?
– My header files depend on one another, how do I solve this circular dependency?
– What’s wrong with the C++ hello world?
– Why do I need header files?
– Why does my application runs in debug mode but not in release?
– How can I debug my release build?

– How do I call a method from another class?

Static methods can be called directly, i.e., without having to instantiate the class but these don’t allow us to change any data that isn’t static so this is probably not what you want to do. There are several ways to call a method other than static, here is described the most common way. You need to have an object (instance) of that class and call the method through that object. Next is the code in 3 different languages, C++, C++ CLI and C#:

A.h

class B;
class A
{
public:
    A(B* b);
    void Func();
    void Print();

private:
    B* m_b;
};
<p>

A.cpp

#include <iostream>
#include "A.h"
#include "B.h"

A(B* b)
{
    m_b = b;
}

void A::Func()
{
    m_b->Func();
}

void A::Print()
{
  std::cout << "A";
}

B.h

class A;
class B
{
public:
    B(A* a);
    void Func();
    void Print();

private:
    A* m_a;
};

B.cpp

#include <iostream>
#include "B.h"
#include "A.h"

B(A* a)
{
    m_a = a;
}

void B::Func()
{
    m_a->Func();
}

void B::Print()
{
  std::cout << "B";
}

A.h

ref class B;
ref class A
{
public:
    A(B^ b);
    void Func();
    void Print();

private:
    B^ m_b;
};

A.cpp

#include <iostream>
#include "A.h"
#include "B.h"

A(B^ b)
{
    m_b = b;
}

void A::Func()
{
    m_b->Func();
}

void A::Print()
{
  std::cout << "A";
}

B.h

ref class A;
ref class B
{
public:
    B(A^ a);
    void Func();
    void Print();

private:
    A^ m_a;
};

B.cpp

#include <iostream>
#include "B.h"
#include "A.h"

B(A^ a)
{
    m_a = a;
}

void B::Func()
{
    m_a->Func();
}

void B::Print()
{
  std::cout << "B";
}

A.cs

class A
{
public A(B b)
{
    m_b = b;
}

public void Func()
{
    m_b.Print();
}

public void Print()
{
    System.Diagnostics.Debug.WriteLine("A");
}

private B m_b;
}

B.cs

class B
{
public B(A a)
{
    m_a = a;
}

public void Func()
{
    m_a.print();
}

public void Print()
{
    System.Diagnostics.Debug.WriteLine("B");
}

private A m_a;
};

– How do I solve linking errors?

Linking/linkage errors happen when you are not linking your project with a library that contains the definition of a function you’re using from that library. They may also happen when you have a declaration of a function but you don’t implement it and then you use it somewhere. It will give a link error with your function’s name. If you’re using the Visual Studio IDE you may choose to which libraries you want to link by going to the project properties->linker->input->additional dependencies and add the correct respective libraries. If you’re using some functions from the windows api, you’ll probably need one or more of the following libraries: shell32.lib, kernel32.lib, user32.lib.

– My header files depend on one another, how do I solve this circular dependency?

You can solve this by either changing the logic of your program and removing the dependency from one class in the other (having only one class depending instead of both) or you can use forward declarations to solve this circular dependency.

A.h

class B;

class A
{
private:
    B* m_b;
};

B.h

class A;

class B
{
private:
    A* m_a;
};

Since A depends on B and B on A, if we try to include B.h in A.h and vice versa, we’ll get a compiler error. To overcome this you have to use forward declarations shown in the example and make sure that the class isn’t being used (this includes holding an instance of a class instead of a pointer or reference to an object of the class). The forward declaration tells the compiler that there’s a type named A (or B depending of the file) but doesn’t give the compiler any information about that type and that’s the reason why you can’t call any methods or use a forward declared class. In the respective source files (cpp files) you may include both A.h and B.h and use the classes as you wish. Note that there’s no problem when you include both header files in the .cpp files because there’s no circular dependency.

– What’s wrong with the C++ hello world?

#include <iostream>

int main()
{
    cout << "Hello World!";
    return 0;
}

I have crossed with many people learning C++ that can’t compile the hello world in some books. If you’re one of those that have problems compiling this code then you should better double check if the book/tutorial is worth your time. The code doesn’t compile because cout isn’t accessible this way. All types/objects/functions of the C++ standard library are in a namespace called std. Namespaces allow you to group types/objects/functions under a name. So to correct your hello world you could do one of the following:

#include <iostream>
using namespace std;
int main()
{
    cout << "Hello World!";
    return 0;
}
#include <iostream>
using std::cout;
int main()
{
    cout << "Hello World!";
    return 0;
}
#include <iostream>

int main()
{
    std::cout << "Hello World!";
    return 0;
}

– Why do I need header files?

You don’t but for large projects it’s advisable that you use header files. Usually header files contain declarations that later may be used in different files by including this header file. By separating declarations from the actual implementations you get some advantages:

  • The interface (declarations in the header file) is separated from the implementation (definitions in the source files).
  • Better structured files for better reading of interfaces.
  • It helps reusing / maintaining the code.

– Why does my application runs in debug mode but not in release?

Debug and release modes don’t actually “exist”, they are just compiler settings which cause the application to behave differently. In debug mode the compiler sets/clears/initializes the variables so it can track memory allocations/writings and this doesn’t happen (unless you changed the configurations) when you compile in release mode. These uninitialized variables may cause a crash in your program. This is not the only cause of the crashes in release mode but is one very common.
Note: Also be careful with code that is only ran in one or other configuration settings either by using macros (#ifdef #endif) and/or assert’s.
One remote possibility is the compiler causing the crash when optimizing your code. Optimizations are usually turned on in release configurations to speed up our application and due to these changes the compiler may introduce a bug in your code.

– How can I debug my release build?

Yes, it is possible to debug release builds. Under Visual Studio go to:

Project Properties->C/C++->Debug Information Format->Program Database
Project Properties->Linker->Debugging->Generate Debug Info->Yes

Now you can debug your program but be aware that if you have optimizations turned on then you may not see the instruction pointer (yellow arrow) in the right place because the optimizations make the code change or even disappear (whenever it’s not needed) from the final build.

Tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *