Forward declaration issues - c++

Here is my issue.
I have 2 classes which I want to implement in 1 h file
lets call them class Foo and class Bar. My issue is that Bar has functions which have a return value of Foo and Foo has functions with a return value of Bar.
Therefore, how do I properly forward declare these so they can play nice with each other.
Thanks

class Foo;
class Bar{
public:
Foo * getMyFoo();
private:
Foo * mMyFoo;
};
class Foo{
public:
void setMyBar(Bar *);
private:
Bar * mTheBar;
};

It's fairly easy..
class A; // yay, forward declared A
class B {
private:
A* fPtrA;
public:
void mymethod(const& A) const;
};
And a more comprehensive guide: http://www.eventhelix.com/RealtimeMantra/HeaderFileIncludePatterns.htm
Which also shows how to handle cyclical dependency:
/* ====== x.h ====== */
// Forward declaration of Y for cyclic dependency
class Y;
class X
{
Y *m_y;
...
};
/* ====== y.h ====== */
// Forward declaration of X for cyclic dependency
class X;
class Y
{
X *m_x;
...
};

You can't return by value in this situation. You'll have to pass into the function by reference or pointer, and populate that value.
void stuff(Foo *output)
{
//change output;
}
Or you can return a reference or pointer:
Foo * stuff()
{
return &my_foo;
}

Yes you can do what you asked returning by value in both classes
Header
class Foo;
class Bar{
public:
Foo getMyFoo();
};
class Foo{
public:
Bar getMyBar();
};
Body
Foo Bar::getMyFoo(){
return Foo();
}
Bar Foo::getMyBar(){
return Bar();
}
However, as other have indicated you cannot hold member variable of the other type in each class (you could do it 1 way only) at which point you start to look at pointers and probably shared_ptr and weak_ptr to maintain the relationships and then why would you want to return by value.

you can also declare a type within the other type - considering their co-dependence, it is often a good idea.
you can defer instantiation of one interface by using a template.

Related

Why use 'struct' keyword in class pointer declaration in C++

When and why should we use the 'struct' keyword when declaring a class pointer variable in C++?
I've seen this in embedded environments so I suspect that this is some kind of hold over from C. I've seen plenty of explanations on when to use the 'struct' keyword when declaring a struct object as it relates to namespaces in C (here), but I wasn't able to find anyone talking about why one might use it when declaring a class pointer variable.
Example, in CFoo.h:
class CFoo
{
public:
int doStuff();
};
inline Foo::doStuff()
{
return 7;
}
And later in a different class:
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
There's rarely a reason to do this: it's a fallover from C and in this case the programmer is simply being sentimental - perhaps it's there as a quest for readability. That said, it can be used in place of forward declarations.
In some instances you might need to disambiguate, but that's not the case here. One example where disambiguation would be necessary is
class foo{};
int main()
{
int foo;
class foo* pf1;
struct foo* pf2;
}
Note that you can use class and struct interchangeably. You can use typename too which can be important when working with templates. The following is valid C++:
class foo{};
int main()
{
class foo* pf1;
struct foo* pf2;
typename foo* pf3;
}
There are two reasons to do this.
The first one is if we are going to introduce a new type in the scope using an elaborated name. That is in this definition
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
the new type struct CFoo is introduced in the scope provided that it is not yet declared. The pointer may point to an incomplete type because pointers themselves are complete types.
The second one is when a name of a class is hidden by a declaration of a function or a variable. In this case we again need to use an elaborated type name.
Here are some examples
#include <iostream>
void CFoo( const class CFoo * c ) { std::cout << ( const void * )c << '\n'; }
class CFoo
{
public:
int doStuff();
};
int main()
{
class CFoo c1;
return 0;
}
Or
#include <iostream>
class CFoo
{
public:
int doStuff();
};
void CFoo( void ) { std::cout << "I am hidding the class CGoo!\n"; }
int main()
{
class CFoo c1;
return 0;
}
In C, two different styles are the most common:
typedef struct { ... } s; with variables declared as s name;.
struct s { ... }; with variables declared as struct s name;
In C++ you don't need to typedef to omit the struct keyword, so the former style is far more in line with the C++ type system and classes, making it the most common style in C++.
But then there are not many cases in C++ when you actually want to use struct instead of class in the first place - structs are essentially classes with all members public by default.
The reason for this may be as simple as not having to include a header file whose contents aren't needed other than for announcing that CFoo names a type. That's often done with a forward declaration:
class CFoo;
void f(CFoo*);
but it can also be done on the fly:
void f(struct CFoo*);

Class typedef defined outside of class

I am writing a class C which has an inner class T, and I'd like the details of T hidden as an internal implementation of C. Methods in C are all using pointers to T. This is of course possible as:
// In header
class C {
public:
class T;
T* f();
void g(T*);
};
// In .cpp
class C::T { /* details here */ };
Now my question is, how can I define C::T as a type alias of another one, in .cpp file. The following doesn't compile at all, but it illustrates what I want to do:
// Outside the class C
using C::T = std::string;
Is there any workaround to this, while maintaining the goal, i.e. hide the detail of C::T?
As others pointed out, it cannot be done. This is my suggestion:
// .h
class C {
public:
struct T;
T* f();
void g(T*);
};
// .cpp
struct C::T
{
IMPL_TYPE data;
//If one is carefull with lifetimes this can almost in any context act as IMPL_TYPE.
//And if necessary, the data member can be accessed.
operator IMPL_TYPE&(){return data};
}
You cannot, because the forward declaration class T; within class C declares a class type whose True Name is C::T, and is therefore not identical to the type whose True Name is std::basic_string<...>.
You might consider the following:
// C.h
#include "internal/T.h"
namespace foo {
class C {
public:
using T = internal::T;
// ...
};
}
// internal/T.h
namespace foo { namespace internal {
using T = std::string;
}}
The closest you can come to this would be to have your t derive from string:
class C::T : public std::string { ... };
T can never be truly hidden or redefined to be a type alias in a different .cpp file.
The following round about method should work for your needs.
class C
{
public:
// Use a base class for just the pointers.
struct TBase
{
virtual ~TBase() {}
};
TBase* f();
void g(TBase*);
// Allow client code to define a concrete type using a template parameter.
template <typename Data> struct T : TBase
{
Data data;
};
};
Then, in a .cpp file, use:
using Type = C::T<std::string>;
Type* obj = new Type;
obj->data = "Some string";
C c;
c.g(obj);
TBase* ptr = c.f();

Pimpl, private class forward declaration, scope resolution operator

Consider these two classes that employ the Pimpl idiom:
ClassA: Pimpl class forward declaration and variable declaration on separate lines
ClassA.h:
#include <memory>
class ClassA {
public:
ClassA();
~ClassA();
void SetValue( int value );
int GetValue() const;
private:
class ClassA_Impl;
// ^^^^^^^^^^^^^^ class forward declaration on its own line
std::unique_ptr<ClassA_Impl> m_pImpl;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable declaration on its own line
//EDIT:
//Even if we use a raw pointer instead of a smart pointer,
//i.e. instead of declaring the smart pointer above, if we declare:
ClassA_Impl *m_pImpl;
//the situation in the *.cpp files and my questions (below) are the same.
};
ClassA.cpp:
#include "ClassA.h"
class ClassA::ClassA_Impl {
public:
void SetValue( int value );
int GetValue() const;
private:
int value_;
};
// Private class implementation
void
ClassA::ClassA_Impl::SetValue( int value ) {
value_ = value;
}
int
ClassA::ClassA_Impl::GetValue() const {
return value_;
}
// ClassA implementation
ClassA::ClassA() : m_pImpl( new ClassA_Impl() ) {}
ClassA::~ClassA() {}
void
ClassA::SetValue( int value ) {
m_pImpl->SetValue( value );
}
int
ClassA::GetValue() const {
return m_pImpl->GetValue();
}
ClassB: Pimpl class forward declaration and variable declaration on one line
ClassB.h:
#include <memory>
class ClassB {
public:
ClassB();
~ClassB();
void SetValue( int value );
int GetValue() const;
private:
std::unique_ptr<class ClassB_Impl> m_pImpl;
// ^^^^^^^^^^^^^^^^^^ class forward declaration
// combined with variable declaration on one line,
// in one shot.
//EDIT:
//Even if we use a raw pointer instead of a smart pointer,
//i.e. instead of declaring the smart pointer above, if we declare:
class ClassB_Impl *m_pImpl;
//the situation in the *.cpp files and my questions (below) are the same.
};
ClassB.cpp:
#include "ClassB.h"
class ClassB_Impl {
public:
void SetValue( int value );
int GetValue() const;
private:
int value_;
};
// Private class implementation
void
ClassB_Impl::SetValue( int value ) {
value_ = value;
}
int
ClassB_Impl::GetValue() const {
return value_;
}
// ClassB implementation
ClassB::ClassB() : m_pImpl( new ClassB_Impl() ) {}
ClassB::~ClassB() {}
void
ClassB::SetValue( int nValue ) {
m_pImpl->SetValue( nValue );
}
int
ClassB::GetValue() const {
return m_pImpl->GetValue();
}
Questions:
Why does combining the forward declaration and variable declaration on one line in ClassB.h require ClassB_Impl to be "unscoped" in the implementation of the private class in ClassB.cpp?
i.e. in ClassA.cpp, private class method definitions begin with
void ClassA::ClassA_Impl::foo() {...
but in ClassB.cpp, private class method definitions begin with
void ClassB_Impl::foo() {...
What are the implications of each method? Which one is better?
(Follow-up question in response to Galik's answer)
When you combine forward declaration of a class and declaration of a variable of that class in one statement...
//one-liner
class ClassB_Impl *m_pImpl;
...what is this called? Is there a name for this kind of combined statement? And why exactly doesn't ClassB_Impl become an inner class of ClassB as a result of such a statement?
Compare this to...
//two-liner
class ClassA_Impl;
ClassA_Impl *m_pImpl;
...in which case ClassA_Impl does become an inner class of ClassA.
Why does the one-liner put ClassB_Impl into the global namepace, while the two-liner puts ClassA_Impl into ClassA's namespace? Why are they different?
Why does combining the forward declaration and variable declaration on
one line in ClassB.h require ClassB_Impl to be "unscoped" in the
implementation of the private class in ClassB.cpp?
Because in the first example you declare ClassA_Impl as an inner class of ClassA.
When you declare ClassB_Impl it in the template parameter that is not part of ClassB.
What are the implications of each method? Which one is better?
This is a matter of opinion. Personally I think inner classes are messy and harder to work with for little reward.
My preferred method uses a separate interface class which helps to reduce the number of times you have to redeclare the interface.
See: Is it possible to write an agile Pimpl in c++?

Forward declarated class with default value

I have a forward declaration but want to have a instatance of the forward declarated class as default value.
So my code looks more or less like this:
bar.h
class Foo;
class Bar
{
public:
Bar();
void test(Foo foo = Foo(7));
}
and foo.h
class Foo
{
public:
Foo(int val);
}
Is this even possible?
No. When you declare a method/function which argument is Foo the compiler should already know the size of Foo, so it should be already defined at that moment. If you declared but not defined Foo you may use only pointers or references to it.
It's impossible as described in another answer.
Apart of that, default values are the code smell. They make your interfaces fragile
Use method overloading instead:
class Foo;
class Bar
{
public:
Bar();
void test(); // implement with default value, and document it
void test(Foo foo); // implement with user-supplied value
}
In bar.cpp:
#include "foo.h" // Complete Foo is available here
void Bar::test()
{
test(Foo(42));
}
void Bar::test(Foo foo)
{
...
}

C++ Calling a function from another class

Very new to c++ having trouble calling a function from another class.
Class B inherits from Class A, and I want class A to be able to call a function created in class B.
using namespace std;
class B;
class A
{
public:
void CallFunction ()
{
B b;
b.bFunction();
}
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
It all looks fine on screen (no obvious errors) but when I try to compile it i get an error C2079 'b' uses undefined class B.
I've tried making them pointers/ friends but I'm getting the same error.
void CallFunction ()
{ // <----- At this point the compiler knows
// nothing about the members of B.
B b;
b.bFunction();
}
This happens for the same reason that functions in C cannot call each other without at least one of them being declared as a function prototype.
To fix this issue we need to make sure both classes are declared before they are used. We separate the declaration from the definition. This MSDN article explains in more detail about the declarations and definitions.
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{ ... }
};
void A::CallFunction ()
{
B b;
b.bFunction();
}
What you should do, is put CallFunction into *.cpp file, where you include B.h.
After edit, files will look like:
B.h:
#pragma once //or other specific to compiler...
using namespace std;
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
B.cpp
#include "B.h"
void A::CallFunction(){
//use B object here...
}
Referencing to your explanation, that you have tried to change B b; into pointer- it would be okay, if you wouldn't use it in that same place. You can use pointer of undefined class(but declared), because ALL pointers have fixed byte size(4), so compiler doesn't have problems with that. But it knows nothing about the object they are pointing to(simply: knows the size/boundary, not the content).
So as long as you are using the knowledge, that all pointers are same size, you can use them anywhere. But if you want to use the object, they are pointing to, the class of this object must be already defined and known by compiler.
And last clarification: objects may differ in size, unlike pointers. Pointer is a number/index, which indicates the place in RAM, where something is stored(for example index: 0xf6a7b1).
class B is only declared but not defined at the beginning, which is what the compiler complains about. The root cause is that in class A's Call Function, you are referencing instance b of type B, which is incomplete and undefined. You can modify source like this without introducing new file(just for sake of simplicity, not recommended in practice):
using namespace std;
class A
{
public:
void CallFunction ();
};
class B: public A
{
public:
virtual void bFunction()
{
//stuff done here
}
};
// postpone definition of CallFunction here
void A::CallFunction ()
{
B b;
b.bFunction();
}
in A you have used a definition of B which is not given until then , that's why the compiler is giving error .
Forward declare class B and swap order of A and B definitions: 1st B and 2nd A. You can not call methods of forward declared B class.
Here's my solution to the issue. Tried to keep it straight and simple.
#include <iostream>
using namespace std;
class Game{
public:
void init(){
cout << "Hi" << endl;
}
}g;
class b : Game{ //class b uses/imports class Game
public:
void h(){
init(); //Use function from class Game
}
}A;
int main()
{
A.h();
return 0;
}
You can also have a look at the curiously recurring template pattern and solve your problem similar to this:
template<typename B_TYPE>
struct A
{
int callFctn()
{
B_TYPE b;
return b.bFctn();
}
};
struct B : A<B>
{
int bFctn()
{
return 5;
}
};
int main()
{
A<B> a;
return a.callFctn();
}