Foo.h
class Foo{
private:
void printSpecialBar(Bar b);//syntax error: Identifier Bar
Foo.cpp
#include "Bar.h"
void Foo::printSpecialBar(Bar b)
{
//code goes here
}
Bar has the default constructor and one that takes two int's.
What is the problem with the syntax error? I tried using the scope resuloution operator Bar::Bar b but it didn't fix it.
A typical practice would be to put
class Bar;
in Foo.h, before any reference to Bar class, and include the actual class like
#include "Bar.h"
in Foo.cpp.
Since Foo.h references Bar, either use a forward declaration or #include "Bar.h" in Foo.h
Related
Suppose we have two classes Foo and Bar.
We can declare the Foo class and use its methods as following:
#include"foo.h"
Foo foo
class Bar{
Bar(){
foo.method1();
}
}
And we have the forward declaration, which stands to declare the Foo class as following:
#include"foo.h"
class Foo
class Bar{
Bar(){
}
}
What are the main differences between the two declartions, and when the forward declaration is prefered to the normal declaration?
In second case you don't need
#include"foo.h"
In forward declaration you just say compiler "There are Foo class somewhere. But I don't know how it look". So compiler can refer them but can't use them;
class Foo; //Forward declaration.
Foo* foo; // ok. Just pointer.
Foo foo;// error. Compiler can't instantiate object.
and
#include "foo.h"
Foo* foo; // ok. Just pointer.
Foo foo;// ok. Compiler can instantiate object.
So, in some case forward declaration can replace the inclusion of a header file.
Is there any difference (no matter how tiny is) between those three methods of defaulting the constructor of a class:
Directly in the header using {}:
//foo.h
class foo{
public:
foo(){}
}
Directly in the header using default keyword:
//foo.h
class foo{
public:
foo()=default;
}
In the cpp using {}
//foo.h
class foo{
public:
foo();
}
//foo.cpp
#include "foo.h"
foo::foo(){}
Yes, there is a difference.
Option 1 and 3 are user-provided. A user-provided constructor is non-trivial, making the class itself non-trivial. This has a few effects on how the class can be handled. It is no longer trivially copyable, so cannot be copied using memcpy and the like. It is also not an aggregate, so cannot be initialized using aggregate-initialization
A fourth option is the following:
//foo.h
class foo{
public:
foo();
}
//foo.cpp
#include "foo.h"
foo::foo()=default;
Although this may seem analogous to your second example, this is actually user-provided as well.
Functionally, the defaulted constructor does the same thing as your foo(){}, as specified in [class.ctor]/6.
I have a "Foo.cpp" class and a "Bar.cpp" class. I want to overload the + operator on two arguments of Foo so that adding two Foos returns a Bar with a value that's the product of their values. The code looks like
//Foo.h
class Foo
{
public:
double foo_val;
Foo();
Foo(double);
};
Bar* operator+ (Foo&, Foo&)
.
//Foo.cpp
#include "Foo.h"
Foo::Foo(){foo_val = 0;}
Foo::Foo(double d){foo_val = d;}
Bar* operator+ (Foo& f1, Foo& f2){
return new Bar(f1.foo_val*f2.foo_val);
}
.
#include "Foo.h"
#include "Bar.h"
int main(){
Foo f1 = new Foo(4, 5);
Foo f2 = new Foo(1, 2);
Bar = f1+f2;
}
Bar is basically identical to Foo at the moment, and it has a constructor "Bar(double);"
It doesn't work at the moment, I think because Bar hasn't been defined before I try to make a new one. (The compiler error is "'Bar' does not name a type") However, I know I can't forward declare Bar at the top because that only works for pointers, whereas I'm trying to construct a new one. Is there some way to get this type of thing to work, or am I going about this totally wrong?
Thanks!
It's actually very simple. In Foo.h, you need to forward declare class Bar, so that the declaration of operator+ is valid:
class Bar;
class Foo
{
// ...
};
Bar* operator+ (Foo& f1, Foo& f2);
Then, in Foo.cpp, you need to include Bar.h since here you really need to know how Bar is declared:
#include "Foo.h"
#include "Bar.h"
// ...
Bar* operator+ (Foo& f1, Foo& f2)
{
// Now you can use Bar's constructor
return new Bar(...);
}
There are two options.
(1) Put
#include "Bar.h"
at the beginning of Foo.h. But if Bar.h already has #include "Foo.h", this will cause a circular dependency, so this is not a viable option.
(2) Put
class Bar;
in Foo.h, before the class definition of Foo.
So lets say I have a class called Foo and another called Bar. Bar contains an instance of Foo and I have a function in Foo that takes Bar as a parameter. However, when I #include "Bar.h" in Foo to allow Foo to see Bar I get this error on the lines that Bar is referenced on:
error: ISO C++ forbids declaration of 'Foo' with no type
I'm guessing this is because both of the classes rely on each other to compile. Is there any way to get around this?
EDIT: Both of these classes have header files where the other class is referenced inside a #ifndef declaration.
In Foo.h instead of including Bar.h you need to use the forward declaration class Bar;. Note that for this to work you need to take the parameter Bar as a reference or a pointer in Foo class.
class Foo;
class Bar
{
};
and
class Bar;
class Foo
{
};
But this might be a result of a wrong design!!
You'll need to use a forward declaration for at least one class:
Foo.h:
#include "Bar.h"
class Foo {
};
Bar.h:
class Bar;
#include "Foo.h"
class Bar {
};
Also beware that you cannot easily reference members of Bar in Foo.h (they're not declared). So any inlined members that need Bar will have to go in Foo.cpp (or .cc if you prefer). You also cannot have a Bar as a value member of Foo.
So:
class Bar {
Foo f; // OK. Compiler knows layout of Foo.
};
class Foo {
Bar b; // Nope. Compiler error, details of Bar's memory layout not known.
Bar *b; // Still OK.
};
This is especially tricky for templates. See the FAQ if you have troubles.
Use references or pointers for parameters and forward declarations. E.g.
//foo.h
class Bar;// the forward declaration
class Foo {
void myMethod(Bar*);
};
//foo.cpp
#include "bar.h"
void Foo::myMethod(Bar* bar){/* ... */}
//bar.h
#include "foo.h"
class Bar {
/*...*/
Foo foo;
};
I want to hide an implementation in implementation file. If the object is not public, I don't want the object's header to leak everywhere my class is used.
Suppose I have header file A.h for my class A:
#include "Foo.h"
class A{
private:
Foo foo;
public:
do_stuff();
};
Now wherever I would include A.h, Foo.h also would be included. But I have no use for class Foo anywhere outside of class A. I would rather not have this #include "Foo.h" line. Is there any way to move the declaration of 'foo' variable inside the implementation A.cpp?
I suspect one possible solution involves adding a layer of abstract class (interface analogy). Is it the best solution?
Thank you.
Use a pointer to Foo and allocate it dynamically, rather than using a member object. Then you only need to include Foo.h in A.cpp.
class Foo;
class A{
private:
Foo* foo;
public:
do_stuff();
}
David's got the right answer. I'll refer to this article for a little more treatment on this kind of "opaque pointer" trick, as you can get more elaborate with it, depending on your needs:
http://en.wikipedia.org/wiki/Opaque_pointer
Also, it's a good idea to use shared_ptr types for this purpose instead of raw pointers like the sample. This will take care of cleaning up resources for you automatically, once the last reference to Foo goes out of scope.
Yes. Choose yer poison!
Option 1. Forward declaration in interface.
class A {
private:
class Foo;
Foo* foo;
};
Option 2. ABC.
// A.hpp
class A {
public: virtual void do_stuff() = 0;
};
// A.cpp
class A_impl : public A {
class Foo { /*etc*/ };
Foo foo;
void do_stuff (){...}
};
Option 3. Private is private. It's "hidden" as far as the public API goes, which is all that matters:
class A {
private:
class Foo {
...
};
private_::Foo foo;
public:
do_stuff();
};
Option 4. Just put the declaration in a "non-public" namespace.i.e., omit it from documentation and name it something to frighten away prying eyes:
namespace private_ {
class Foo {
...
};
}
class A {
private:
private_::Foo foo;
public:
do_stuff();
};