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)
{
...
}
Related
I have this error for the following code
incomplete type ‘Foo::Pimpl’ used in nested name specifier
AnotherFoo.hpp
struct AnotherFoo {
void methodAnotherFoo(Foo &);
};
AnotherFoo.cpp
#include "Foo.hpp"
#include "AnotherFoo.hpp"
void AnotherFoo::methodAnotherFoo(Foo &foo) {
// here i want to save the function pointer of methodPimpl(), std::function for ex:
std::function<void(void)> fn = std::bind(&Foo::Pimpl::methodPimpl, foo._pimpl); // <-- Here i am getting the error
}
Foo.hpp
struct Foo {
Foo();
class Pimpl;
std::shared_ptr<Pimpl> _pimpl;
};
Foo.cpp
#include "Foo.hpp"
struct Foo::Pimpl {
void methodPimpl(void) {}
};
Foo::Foo() : _pimpl(new Pimpl) {}
main.cpp
#include "Foo.hpp"
#include "AnotherFoo.hpp"
int main() {
Foo foo;
AnotherFoo anotherFoo;
anotherFoo.methodAnotherFoo(foo);
}
Does anyone have a good solution for how to fix this?
The main goal that I am trying to achieve is to keep the signature of the methodAnotherFoo method hidden from the header files.
The only file in which you may access details of Foo::Pimpl is Foo.cpp, the file in which it is defined.
You may not access it in AnotherFoo.cpp.
Your choices are:
Change the implementation of AnotherFoo::methodAnotherFoo to use only the public interface of Foo.
Move the implementation of AnotherFoo::methodAnotherFoo to Foo.cpp.
If AnotherFoo.cpp needs direct access to the implementation object it is going to have to see the definition of that type, there is no way around that. Perhaps add a "detail/foo.h" header that is meant for internal use like this.
Your Pimpl implementation is not correct. It should hide details while you are trying to access them directly from methodAnotherFoo. So you should make implementation details private and provide a public proxy methods to manipulate stored implementation:
class Foo
{
public: Foo();
public: void method(void);
private: class Pimpl;
private: std::shared_ptr<Pimpl> _pimpl;
};
// Foo.cpp
struct Foo::Pimpl
{
void methodPimpl(void) {}
};
Foo::Foo() : _pimpl(new Pimpl) {}
void Foo::method(void) {_pimpl->method();}
And change the rest of the code to utilize those proxy methods instead of digging to implementation details:
void AnotherFoo::methodAnotherFoo(Foo &foo)
{
std::function<void(void)> fn = std::bind(&Foo::method, foo);
}
One solution that i found is to move the Pimpl implementation to AnotherFoo.cpp
I am going through some code which is a little un-organized.
I would like to use a class created in a cpp file used as an argument type in its header file. I know the class needs to be defined in the header but I am currently looking for a short approach here for now. This is what I have
filename: foo.cpp
class bar {
}
Now the header
filename: foo.h
class teacher {
public:
void dosomething(bar b) { ///<-----Incomplete type.
b.work(); ///
}
}
I tried declaring a prototype inside the header this way
class foo;
class teacher {
public:
void dosomething(bar b) {
b.work(); ///Error no method work for incomplete type.
}
}
What would be the simplest way to fix this issue apart from moving the bar class to the header file
You can forward-declare the type bar in the header assuming you do nothing that relies on it being a complete type. For example, this won't work:
// foo.hpp
class bar;
class teacher {
public:
void dosomething(bar b) {
// Will fail, bar is not complete:
b.work();
}
};
But this will:
// foo.hpp
class bar;
class teacher {
public:
void dosomething(bar b);
};
// foo.cpp
class bar {
public:
void work() {}
};
void teacher::dosomething(bar b) {
b.work();
}
However, I would advise instead to create a bar.hpp file with the definition of the bar type and #include it into foo.hpp.
Consider, for example, that any code (other than foo.cpp) that includes foo.hpp will be unable to invoke teacher::dosomething(bar), since it won't have any definition for bar.
I think it will be better like this :
File : bar.hh
class bar
{
...
}
File : foo.hh
#include "bar.hh"
class teacher
{
public:
void dosomething(bar b)
{
b.work();
}
}
Is there any way to access a variable in all of my methods in a class(except using global varibles that defines above of cpp file)??
TIA
foo.h
class Foo {
static int bar;
void foo ();
};
void foo ();
foo.cpp
int Foo :: bar = 123;
void Foo :: foo () {
++bar; // ok
}
void foo () {
++ bar; // Error! Not in scope.
++ Foo :: bar; // Error! Private.
}
You mean a static data member of the class?
The other answers are correct, but I didn't read your question as meaning it is the same across Foo objects which is what making it as static here will do (as well as making it interesting across multi-threaded code). You can also make it just a private variable such as here:
Header:
class Foo
{
private:
int bar;
void foo ();
public:
Foo();
};
Class:
Foo::Foo() : bar(123) {}
void Foo :: foo ()
{
// Will update its own bar, but not every other Foo object that exists
++bar; // ok
}
But maybe the static way is what you wanted :-)
I have this:
//forward declaration of Foo <-- this is my question
void doSome(Foo foo);
typedef void* Foo; //Foo is defined later as void*
void doSome(Foo foo)
{
//code here..
}
How can I forward declare Foo in a way compatible with void*?
This is an oversimplified example, of course is trivial here, but the idea is having multiple implementations, like this:
//forward declaration of Foo <-- this is my question
void doSome(Foo foo);
//[implementation1_internal.h]
typedef void* Foo; //Foo is defined later as void*
void doSome(Foo foo)
{
//code here..
}
//[implementation2_internal.h]
typedef int* Foo; //Foo is defined later as int*
void doSome(Foo foo)
{
//code here..
}
and select one of them using preprocessor directives. (This is irrelevant, just to show the example is not just silly).
Why cannot you put typedef before. If you declare function having an argument of given custom type (be it class or typedef) you need to somehow declare this class as well.
As in case of pointers to class/struct, the size is perfectly well known even if the class member are not known (=sizeof(pointer)), in case of typedef'ed types, the size cannot be known unless you provide your the full typedef declaration.
Therefore, the solution is to place typedef before your function declaration.
You should have:
// declarations
typedef void* Foo; //Foo is defined later as void*
void doSome(Foo foo);
// definitions
void doSome(Foo foo)
{
//code here..
}
If you cannot modify the definitions due to some reason, you can repeat typedef twice (as long as both are non-conflicting / exactly the same):
// declarations
typedef void* Foo;
void doSome(Foo foo);
// definitions
typedef void* Foo;
void doSome(Foo foo)
{
//code here..
}
EDIT after question edit
The best way would be to have overloaded functions:
void doSome(void* foo)
{
// void* version
}
void doSome(int* foo)
{
// int* version
}
It is not a good idea to have different Foos around your project.
typedef void* Foo;
void doSome(Foo foo);
void doSome(Foo foo)
{
//code here..
}
You only need to forward-declare classes which have implementations. Typedefs don't have implementations.
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.