Reputation: 161
Since desperate times require cranky measures I implemented the following in C++.
-- There is a class called foo. I need an instance (object or reference and not a pointer) of foo in a class called bar.
-- I do not want to declare foo as an object in bar.h since I don't want to include foo.h in bar.h. The reason being bar.h is included in about a hundred .cpp files in the project and including foo.h in bar.h drastically increases the compilation time and brings in spaghetti.
-- I do not want to class forward foo and declare it as a pointer since we are trying to avoid pointers like the plague.
-- The constructor of bar does not pass an instance of foo by argument.
So I did this:
This is foo.h (foo.cpp is a lot of math but is not important in this argument):
#ifndef FOO_H
#define FOO_H
class bell;
class foo {
public:
foo(const bell& bell_i);
virtual ~foo();
double foo_member(); /*does math in foo.cpp*/
};
#endif /* FOO_H */
This is bar.h:
#ifndef BAR_H
#define BAR_H
class bell;
class foo;
class bar {
public:
bar(const bell& bell_i);
virtual ~bar();
double bar_member(); /* does math in bar.cpp and uses foo */
private:
foo& myfoo;
};
#endif /* BAR_H */
This is bar.cpp:
#include "bell.h"
#include "foo.h"
bar::bar(const bell& bell_i) : myfoo(*(new foo(bell_i))) /* NOTE: this construction is my question. */
{}
bar::~bar()
{}
double bar::bar_member()
{
return sqrt(myfoo.foo_member());
}
So, in essence, I am creating a pointer to foo, taking the object from it and initializing myfoo. This code and all associated code compiles perfectly and runs without any errors. I have tested it with multiple compilers.
My questions are:
-- Is there anything wrong code-wise (syntax/lifetimes/dangling pointers etc.) with initializing myfoo as such?
-- Is there anything wrong codeologically with doing this?
-- Am I missing something?
-- Is there an alternative without using pointers?
If you want to see the real code it is here: the .cpp file, the .h file.
Thanks in advance. I am a physicist. So, please excuse my code lingo.
Update: The leaks did not seem to be a problem since only a few instances of the class were constructed at initiation and not destroyed during runtime and only destroyed at exit. But this should not be done for classes that get created and destroyed during runtime.
Upvotes: 0
Views: 139
Reputation: 3156
Use a pointer as the member, but have an accessor Foo &GetFoo() {return *pmyFoo;}
that returns a reference. Make the member private and use the accessor everywhere, even within the class's code.
Except for that one method (oh, and the dtor to free it up), as far as all of your code is concerned, there is no pointer, only a reference.
Upvotes: 0
Reputation: 223
Your measures defy purposes here. Instead of pointer you now have a memory leak as you allocate memory for foo instance anyway, but you never free it. If you need to use pointer/reference, but don't want to keep track of the object lifetime manually, you better use RAII approach, for example, std::unique_ptr. It will hold your object pointer and carefully deallocate it when the time comes.
Upvotes: 4