C++/CLI circular reference issue with CLI Classes - c++

I am having an issue with two classes that reference each other. I have attempted to use an interface to resolve the issue, but run into other problems such as class re-definition. I am just not sure how to do this properly.
here is an example of what I have going on. Note: I have taken out all the extra properties and methods that are not actually affecting this issue. How can I redo these without causing class re-definitions and without the circular reference. If you can, please use this example as a template for a correct layout of the statements.
// componentClass.h
//#include "controlClass.h" - Would cause a circular reference
namespace test
{
//component class
public ref class componentClass sealed : Component
{
internal:
componentClass(controlClass ^control);
private:
controlClass ^_control;
};
}
// controlClass.h
#include "componentClass.h";
namespace test
{
//control class
public ref class controlClass: Control
{
public:
controlClass();
private:
componentClass ^_componentClass;
};
}
// controlClass.cpp
#include "controlClass.h"
controlClass::controlClass()
{
_componentClass = gcnew componentClass(this);
}
// componentClass.cpp
#include "componentClass.h"
componentClass::componentClass(controlClass ^control)
{
_control = control;
}

Generally the easiest way to resolve this issue is to put both class declarations inside of one header file, and forward-declare the second one. For example:
namespace test
{
// Forward declaration of controlClass
ref class controlClass;
//component class
public ref class componentClass sealed : Component
{
internal:
componentClass(controlClass ^control);
private:
controlClass ^_control;
};
//control class
public ref class controlClass: Control
{
public:
controlClass();
private:
componentClass ^_componentClass;
};
}
It's possible to accomplish this with multiple header files, but there are caveats and complexities that are eliminated by using a single header file.
You can continue to provide the implementation of each class in a different source file without problems.

Related

Injecting a Mock using registerConstructor

I've successfully set up a Mock for injection via fruit using .replace(get*Component).with(getMock*Component) like so:
#include <gmock/gmock.h>
#include "mockBar.h"
#include "classUnderTest.h"
namespace foo {
fruit::Component<ClassUnderTest, MockBar> getMainComponent()
{
return fruit::createComponent()
.replace(getBarComponent)
.with(getMockBarComponent)
.install(getClassUnderTestComponent);
}
class ClassUnderTestTest : public ::Testing::Test
{
protected:
fruit::Injector<ClassUnderTest, MockBar> injector{getMainComponent};
MockBar *mockBar{injector};
ClassUnderTest *classUnderTest{injector};
};
// TEST_F declarations
}
For the base mock as I'm writing that myself I have no problems because I can utilise the INJECT() macro on the default constructor and bind the mock to the interface in getMock*Component like so:
#include "bar.h"
namespace foo
{
class MockBar : public Bar
{
public:
INJECT(MockBar()) = default;
// MOCK_METHOD declarations
};
fruit::Component<Bar> getMockBarComponent()
{
return fruit::createComponent()
.bind<Bar, MockBar>();
}
}
For a StrictMock where the constructor is defined in the googlemock library as I understand things I should be using .registerConstructor<StrictMock<Mock*>()>() instead and this is where my problems start.
No explicit binding nor C::Inject definition was found for T.
For the sake of troubleshooting I've removed the INJECT() macro and applied this logic to the base mock like so which gives me the same error when trying to build:
#include "bar.h"
namespace foo
{
class MockBar : public Bar
{
public:
// MOCK_METHOD declarations
};
fruit::Component<Bar> getMockBarComponent()
{
return fruit::createComponent()
.registerConstructor<MockBar()>()
.bind<Bar, MockBar>();
}
}
Tried with registerProvider() like so for the sake of argument but got the same error:
fruit::Component<Bar> getMockBarComponent()
{
return fruit::createComponent()
.registerProvider([](){ return new MockBar; })
.bind<Bar, MockBar>();
}
registerFactory<Mock*()>() would appear to be excessive for what I'm trying to do (I only need the one instance) so I've not tried delving into that.
My presumption because I'm new to both googlemock and fruit and because my C++ experience isn't stellar is there's a nuance I'm missing here regardless of what I've read to the contrary.
Any ideas/suggestions for what I should try next or blaringly obvious errors I've made?
I can abstract out some more of my code if I haven't captured everything of importance here.
Ta in advance!

Mutual Inclusion of header files and class members c++ [duplicate]

I've got two classes, Entity and Level. Both need to access methods of one another. Therefore, using #include, the issue of circular dependencies arises. Therefore to avoid this, I attempted to forward declare Level in Entity.h:
class Level { };
However, as Entity needs access to methods in Level, it cannot access such methods, since it does not know they exist. Is there a way to resolve this without re-declaring the majority of Level in Entity?
A proper forward declaration is simply:
class Level;
Note the lack of curly braces. This tells the compiler that there's a class named Level, but nothing about the contents of it. You can then use pointers (Level *) and references (Level &) to this undefined class freely.
Note that you cannot directly instantiate Level since the compiler needs to know the class's size to create variables.
class Level;
class Entity
{
Level &level; // legal
Level level; // illegal
};
To be able to use Level in Entity's methods, you should ideally define Level's methods in a separate .cpp file and only declare them in the header. Separating declarations from definitions is a C++ best practice.
// entity.h
class Level;
class Entity
{
void changeLevel(Level &);
};
// entity.cpp
#include "level.h"
#include "entity.h"
void Entity::changeLevel(Level &level)
{
level.loadEntity(*this);
}
you two options:
use pointers in which case your forward declares should be ok.
inline the methods of one class, in which case if you include the .h file you can use the methods of the other.
Personally I would go down path number 1, it's cleaner and allows better access. I use a lot of shared_ptr so I do not have to worry about deletes...
Entity.h:
class Level;
class Entity {
private:
Level* m_pLevel;
public:
bool CheckLevel ();
bool WasItThere();
Level.h
class Entity;
class Level {
private:
Entity* m_pEntity;
public:
public bool CheckMyStuff();
public bool CheckItOut() { return m_pEntity->WasItThere();}
}
Entity.cpp
#include "Level.h"
bool Entity::CheckLevel () {
return true;
}
bool Entity::CheckLevel() {
return m_pLevel->CheckMyStuff();
}
bool Entity::WasItThere() {
return true;
}
Level.cpp
bool Level::CheckMyStuff() {
return true;
}
bool Level::CheckItOut() {
return m_pEntity->WasItThere();
}

C++ combining namespaces

I have some shared files that I want to use between two programs A and B that have the same compile target and are very identical.
So, I tried to separate them into two namespaces and create a shared namespace for the shared files
Interfaces.h
namespace ns_s {
class SomeClass;
class IFoo {
virtual void bar(SomeClass*) = 0;
};
}
SomeHeaderinA.h
#include "Interfaces.h"
namespace ns_a {
using namespace ns_s;
class Foo : public IFoo {
virtual void bar(SomeClass* p) override { ... }
};
}
However the compiler is complaining now that my member function bar does not override anything, so it seems to not see the interface implementation.
Why is that the case? And why does the compiler not already complain about a missing class IFoo?
EDIT:
Looks like I missed an essential part that contributes to the problem. I pre-declared a class that is a parameter of the interface method. Now that I ahve a pre-declaration in namespace shared and an actual declaration in namsepace A those things are not the same anymore.
Is there a good way to fix this? Only a small subset of interfaces have arguments that are defined in one or the other namesapce (A or B), so I could leave different implementations in each of them, but it would be nice to have it all in the shared space if possible in a clean fashion.
Here is a link
http://coliru.stacked-crooked.com/a/79fa58e50e7b8637
Problem
As shown in the linked code, the problem is caused by SomeClass.
The line
class SomeClass{};
declares and defines SomeClass in namespace ns_a. It does not define SomeClass in namespace ns_s.
The declaration of class ns_s::IFoo::bar uses ns_s::SomeClass.
The declaration of class ns_a::IFoo::bar uses ns_a::SomeClass.
That's the override is an error.
Solution
You can fix it by:
Removing the definition of SomeClass from ns_a, or
Using ns_s::SomeClass in the declaration of ns_a::IFoo::bar.
namespace ns_a {
using namespace ns_s;
class Foo : public IFoo {
virtual void bar(SomeClass* p) override {}
};
}
or
namespace ns_a {
using namespace ns_s;
class SomeClass{};
class Foo : public IFoo {
virtual void bar(ns_s::SomeClass* p) override {}
};
}

Separate class for a namespace advisable?

I have a couple functions that I want to use in many different classes. I have a couple classes that are derived from one base class and so tried to make it so that the base class held the functions and then the child classes could just call them. This seemed to cause linking errors, and so following advice from this question (Advantages of classes with only static methods in C++) I decided to give namespaces a swing, but the only file that is included by every header/file is resource.h, and I don't want to put a namespace for my functions in there as it seems to specialised to mess with.
My question is, how do I make a class that only includes a namespace, or the functions I want to use, so that I can just include this class and use the functions as desired?
Thank you in advance for the help, the answers I've found on the internet only focus on one file, not multiple files like I'm hoping to address :)
You seem confused about how namespaces are used. Here are some things to keep in mind when working with namespaces:
You create a namespace using the syntax namespace identifier { /* stuff */ }. Everything between the { } will be in this namespace.
You cannot create a namespace inside a user-defined type or function.
A namespace is an open group construct. This means you can add more stuff into this namespace later on in some other piece of code.
Namespaces aren't declared unlike some of the other language constructs.
If you want certain classes and/or functions inside a namespace scope, enclose it with the namespace syntax in the header of where it's defined. Modules using those classes will see the namespace when the headers get #include'd.
For example, in your Entity.h you might do:
// Entity.h
#pragma once
namespace EntityModule{
class Entity
{
public:
Entity();
~Entity();
// more Entity stuff
};
struct EntityFactory
{
static Entity* Create(int entity_id);
};
}
inside your main.cpp you access it like this:
#include "Entity.h"
int main()
{
EntityModule::Entity *e = EntityModule::EntityFactory::Create(42);
}
If you also want Player to be inside this namespace then just surround that with namespace EntityModule too:
// Player.h
#pragma once
#include "Entity.h"
namespace EntityModule{
class Player : public Entity
{
// stuff stuff stuff
};
}
This works because of point #3 above.
If for some reason you feel you need to create a namespace inside a class, you can simulate this to an extent using nested classes:
class Entity
{
public:
struct InnerEntity
{
static void inner_stuff();
static int more_inner_stuff;
private:
InnerEntity();
InnerEntity(const InnerEntity &);
};
// stuff stuff stuff
};
Some important differences and caveats doing it this way though:
Everything is qualified with static to indicate there's no specific instance associated.
Can be passed as a template parameter.
Requires a ; at the end.
You can't create a convenient shorthand with abusing namespace Entity::InnerEntity;. But perhaps this is a good thing.
Unlike namespaces, class and struct are closed constructs. That means you cannot extend what members it contains once defined. Doing so will cause a multiple definition error.
You can put anything in a namespace, but you can't put namespaces inside things ( that's not a very formal way of saying it but I hope you get what I mean.
Valid
namespace foospace
{
class foo
{
public :
foo();
~foo();
void eatFoo();
};
}
Invalid
namespace foospace
{
class foo
{
public :
foo();
~foo();
namespace eatspace
{
void eatFoo();
}
};
}
I'm not 100% certain that the second example wouldn't compile, but regardless, you shouldn't do it.
Now, from your comments it sounds like you want something like this :
In the file Entity.h, your entity class definition :
namespace EntitySpace
{
class Entity
{
public :
Entity();
~Entity();
};
}
In the file Player.h
#include "Entity.h"
namespace EntitySpace
{
class Player : public Entity
{
public :
Player();
~Player();
};
}
In the file main.cpp
#include "Player.h"
int main()
{
EntitySpace::Player p1;
EntitySpace::Player p2;
}
So you call upon Player in the EntitySpace namespace. Hope this answers what you were asking.

Namespace-level access

I have the following situation:
namespace MyFramework {
class A {
void some_function_I_want_B_to_use() {}
};
class B {
B() {
some_function_I_want_B_to_use() {}
}
};
}
where I want the some_function_I_want_B_to_use to not be visible outside of the MyFramework namespace, but I do want it to be visible to anyone inside of MyFramework (alternatively, visible to just class B is also ok). I've got a number of methods like this, is the only way to hide them from the public API of MyFramework to make all classes within MyFramework friends? I was also considering placing all "lower-level" classes inside of B, but I don't want to go down that route until I'm sure it would accomplish the ability to access all of A's methods from inside of B but not from outside of MyFramework.
To restate, I've got a framework that's all created within one namespace, and each class has methods that are useful to the general public using the framework. However, each class also has a few methods that complicate the public API but are needed for the framework to function properly.
I want the some_function_I_want_B_to_use to not be visible outside of the MyFramework namespace, but I do want it to be visible to anyone inside of MyFramework.
In summary, you want something similar to packages in Java.
Unfornately for you, that is not possible with namespaces. Every class included in a namespace is accessible from the outer of the namespace: namespaces are open.
The solution is usually to add another namespace for implementation details:
namespace MyFramework
{
// Implementation details
// Should not be used by the user
namespace detail
{
class A
{
public:
void func();
};
}
class B
{
public:
B()
{
A a;
a.func();
}
};
}
Don't forget to add a comment stating the detail namespace is not to be used by user.
Pimpl idiom, frequently called Compilation Firewall, is what you are looking for. The whole Qt is implemented using this idiom.
// A.hpp
namespace MyFramework {
class A {
private:
class Private;
Private* implementation;
};
}
// A_Private.hpp
#include "A.hpp"
namespace MyFramework {
class A::Private {
public:
void some_function_I_want_B_to_use() {}
};
}
// A.cpp
#include "A_Private.hpp"
namespace MyFramework {
A::A() {
implementation->some_function_I_want_B_to_use();
}
}
// B.hpp
#include "A.hpp"
namespace MyFramework {
class B {
B();
A a;
};
}
// B.cpp
#include "A_Private.hpp"
namespace MyFramework {
B::B() {
a.implementation->some_function_I_want_B_to_use();
}
}
NOTE: Of course A_Private.hpp does not go into the include directory of you framework final distribution, i.e. it remains package private as you require.
The example is very basic. Of course it can be made more advanced and robust. Additionally, Pimpl has lots of other advantages. For all this information refer to:
GotW #100: Compilation Firewalls (Difficulty: 6/10)
GotW #101: Compilation Firewalls, Part 2 (Difficulty: 8/10)
Pimp My Pimpl — Reloaded
Pimp My Pimpl
Dpointer
The common convention, e.g. in Boost, is a nested namespace called detail.
If you want to enforce the accessibility you can always instead use a nested class called detail. The class provides accessibility checking, but lacks extensibility like a namespace. However, a detail scope will rarely if ever need extension.
So, in all its ugliness,
namespace my_framework {
class detail
{
private:
static void some_function_I_want_B_to_use() {}
public:
class A
{};
class B
{
B() { some_function_I_want_B_to_use(); }
};
};
typedef detail::A A; // "using detail::A"
typedef detail::B B; // "using detail::B"
} // namespace my_framework
In passing, note that class B (straight from the question) has a private default constructor so no instances of it can be created.