I'm trying to get Doxygen to ignore an inheritance relationship when drawing collaboration diagrams.
Let's say my class definition looks like this:
class Derived : public Base
{
int x;
int y;
int z;
}
Now, when I run Doxygen, I don't want to see Base class in the generated collaboration diagram.
At first glance, it seems that the cleanest way to do this would be to use the EXCLUDE_SYMBOLS directive in my Doxyfile. Specifically:
EXCLUDE_SYMBOLS = Base
However, I've found that this does not work: The Base class still shows up in my collaboration diagram for Derived. I've tried this on both Doxygen 1.8.6 and 1.8.11 and with different permutations of Base wildcards (Base*, *as*, etc), same behavior. The Base class always shows up in my collaboration diagram.
To be fair, I have found 2 workarounds, but they both involve putting conditional statements into my code. For completeness, I'll include both here:
First Workaround Method:
class Derived :
#ifndef DOXYGEN_SHOULD_SKIP_THIS
public Base
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
{
...
}
Then ensure that the following two directives are set inside the Doxyfile:
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
ENABLE_PREPROCESSING = YES
Second Workaround Method:
class Derived :
/// #cond DOXYGEN_IGNORE
public Base
/// #endcond
{
...
}
To be clear, these workarounds do indeed make Doxygen ignore the inheritance relationship, but I'd prefer not to unnecessarily pollute my code base, especially if there's a better / cleaner way to accomplish my goal.
My question is -- Why doesn't EXCLUDE_SYMBOLS make Doxygen ignore my Base class when it draws the collaboration diagram?
If i am not mistaken, EXCLUDE_SYMBOLS prevents Doxygen from generating documentation for the excluded symbols, but it does not hide them. This means Doxygen won't generate documentation for your Base class, but it will still mention it as the base class of Derived, just like if Derived inherited from a class provided by an external library, the name of the class provided by the library would appear in the collaboration diagram.
I'm working with boost on a project and I would like to use the Bundled Properties mechanism on a class Foo. This is to allow the user to add data like a struct to the class.
Actually, Foo is a class used in similar ways to the edges on a graph in the Boost Graph Library. Foo needs to contains user defined datas (tags, IDs, ...) that the user can handle through visitors during algorithms process for example.
However I was not able to understand how to add this capability to my class Foo with meta programming. Could you explain me some design patterns to do that ?
The idea behind this is simple.
The hosting class take as a template parameter the hosted one.
Once it has it, it just derive from the latter:
template <class T>
template class Host : public T
{
};
As the rules of inheritance specifies, all public members are accessible from the deriven class.
If you want to chain more properties, use multiply inheritance.
Simple and awesome, right?
I've got a class that inherits from another class like so:
class TestClass : public BaseClass
I am wondering if it is possible to make this a test class using the TEST_CLASS macro or some other macro that is part of the Microsoft Unit Testing Framework for C++. I tried:
class TEST_CLASS(TestClass : public BaseClass)
But the IDE gives the error 'Error: expected either a definition or a tag name' and the compiler error is error C3861: '__GetTestClassInfo': identifier not found
I know it's probably bad practice to inherit on a test class but it would make implementing the test easier. I am relatively new to C++ so I am wondering if it is something simple I have missed or if it's just not possible.
Thanks,
There is one other option you didn't include and others may be tripping over this question without knowing the solution.
You can actually derive from any arbitrary type by looking at the macro itself:
///////////////////////////////////////////////////////////////////////////////////////////
// Macro to define your test class.
// Note that you can only define your test class at namespace scope,
// otherwise the compiler will raise an error.
#define TEST_CLASS(className) \
ONLY_USED_AT_NAMESPACE_SCOPE class className : public ::Microsoft::VisualStudio::CppUnitTestFramework::TestClass<className>
As C++ supports multiple inheritance you can easily derive by using code similar to the following:
class ParentClass
{
public:
ParentClass();
virtual ~ParentClass();
};
TEST_CLASS(MyTestClass), public ParentClass
{
};
Just remember that if you are working with resources you will need to have a virtual destructor to have it be called. You will also have to call the initialize & cleanup methods directly if you are going to be using them, because the static methods they create are not called automagically.
Good luck, Good testing!
It's been a while since I used CppUnitTestFramework but back then this site has been a valuable resource for many questions on that topic.
TEST_CLASS is preprocessor macro. You can use it to declare a test class like
TEST_CLASS(className)
{
TEST_METHOD(methodName)
{
// test method body
}
// and so on
}
That's it. As far as I know there is no way to inherit test classes from one another.
Maybe though composition over inheritance might help in your specific case.
I have a situation: In a single Solution I have two Projects. I need to extend the Class:Foo used in Project:A so that I can add new functionality required in Project:B without changing its name. Problem is: Class:Foo already contains (i.e. has a) Class:Bar and is contained by Class:Goo in both Project:A & Project:B. In Project:B I am inheriting Class:Goo into Class:Goo_Ex; but I need to also extend both: Class:Foo and Class:Bar with companion functions.
To make it more clear - I could accomplish this using the following crude method:
/* Project:A-Class:Foo */
class Foo
{
.
.
.
# ifdef PROJECT_B
fnExtended();
# endif
};
but that would litter my code in Project:A.
A possible solution that I can think of is to use Inheritance and have Class:Foo_Global Inherited-[Only] as Class:Foo in Project:A and Inherited-[Extend] as, again, Class:Foo in Project:B; same for Class:Bar. But is their a more straight forward solution..?
I think your proposed solution (to hide the current Foo as some other class name and inherit from it in a new Foo class in both projects) is how you should do it.
This is a really abstract problem, and it's difficult to give you a good specific solution without more details.
The basic way of handling this is inheritance. But this requires some pre-planning. It means that when you refer to Foo in project A, you should use pointers or references. If you create a Foo (and need code from project A create Foo_Extended when it's part of project B) then you need to have a configurable Foo factory that will create objects of the appropriate type depending upon context.
The other way of handling this is templates. You never have the code in project A refer directly to the global Foo class. Instead it always refers to a template parameter. In project A that template parameter will end up resolving to Foo, and in project B it will resolve to some other class that has the needed functionality.
These are the two general ways of handling this issue in C++. And which you use depends a lot on the details of the context in which you're using them.
The way to extend you class is not to extend it! Just use a function taking suitable arguments instead.
I came across this problem via a colleague today. He had a design for a front end system which goes like this:
class LWindow
{
//Interface for common methods to Windows
};
class LListBox : public LWindow
{
//Do not override methods in LWindow.
//Interface for List specific stuff
}
class LComboBox : public LWindow{} //So on
The Window system should work on multiple platforms. Suppose for the moment we target Windows and Linux. For Windows we have an implementation for the interface in LWindow. And we have multiple implementations for all the LListBoxes, LComboBoxes, etc. My reaction was to pass an LWindow*(Implementation object) to the base LWindow class so it can do this:
void LWindow::Move(int x, int y)
{
p_Impl->Move(x, y); //Impl is an LWindow*
}
And, do the same thing for implementation of LListBox and so on
The solution originally given was much different. It boiled down to this:
#define WindowsCommonImpl {//Set of overrides for LWindow methods}
class WinListBox : public LListBox
{
WindowsCommonImpl //The overrides for methods in LWindow will get pasted here.
//LListBox overrides
}
//So on
Now, having read all about macros being evil and good design practices, I immediately was against this scheme. After all, it is code duplication in disguise. But I couldn't convince my colleague of that. And I was surprised that that was the case. So, I pose this question to you. What are the possible problems of the latter method? I'd like practical answers please. I need to convince someone who is very practical (and used to doing this sort of stuff. He mentioned that there's lots of macros in MFC!) that this is bad (and myself). Not teach him aesthetics. Further, is there anything wrong with what I proposed? If so, how do I improve it? Thanks.
EDIT: Please give me some reasons so I can feel good about myself supporting oop :(
Going for bounty. Please ask if you need any clarifications. I want to know arguments for and vs OOP against the macro :)
Your colleague is probably thinking of the MFC message map macros; these are used in important-looking places in every MFC derived class, so I can see where your colleague is coming from. However these are not for implementing interfaces, but rather for details with interacting with the rest of the Windows OS.
Specifically, these macros implement part of Windows' message pump system, where "messages" representing requests for MFC classes to do stuff gets directed to the correct handler functions (e.g. mapping the messages to the handlers). If you have access to visual studio, you'll see that these macros wrap the message map entries in a somewhat-complicated array of structs (that the calling OS code knows how to read), and provide functions to access this map.
As MFC users, the macro system makes this look clean to us. But this works mostly because underlying Windows API is well-specified and won't change much, and most of the macro code is generated by the IDE to avoid typos. If you need to implement something that involves messy declarations then macros might make sense, but so far this doesn't seem to be the case.
Practical concerns that your colleague may be interested in:
duplicated macro calls. Looks like you're going to need to copy the line "WindowsCommonImpl" into each class declaration - assuming the macro expands to some inline functions. If they're only declarations and the implementations go in a separate macro, you'll need to do this in every .cpp file too - and change the class name passed into the macro every time.
longer recompile time. For your solution, if you change something in the LWindow implementation, you probably only need to recompile LWindow.cpp. If you change something in the macro, everything that includes the macro header file needs to be recompiled, which is probably your whole project.
harder to debug. If the error has to do with the logic within the macro, the debugger will probably break to the caller, where you don't see the error right away. You may not even think to check the macro definition because you thought you knew exactly what it did.
So basically your LWindow solution is a better solution, to minimize headaches down the road.
Does'nt answer your question directly may be, but can't help from telling you to Read up on the Bridge Design pattern in GOF. It's meant exactly for that.
Decouple an abstraction from its
implementation so that the two can
vary independently.
From what I can understand, you are already on the right path, other than the MACRO stuff.
My reaction was to pass an
LWindow*(Implementation object) to the
base LWindow class so it can do this:
LListBox and LComboBox should receive an instance of WindowsCommonImpl.
In the first solution, inheritance is used so that LListBox and LComboBox can use some common methods. However, inheritance is not meant for this.
I would agree with you. Solution with WindowsCommonImpl macro is really bad. It is error-prone, hard to extend and very hard to debug. MFC is a good example of how you should not design your windows library. If it looks like MFC, you are really on a wrong way.
So, your solution obviously better than macro-based one. Anyway, I wouldn't agree it is good enough. The most significant drawback to me is that you mix interface and implementation. Most practical value of separating interface and implementation is ability to easily write mock objects for testing purposes.
Anyway, it seems the problem you are trying to solve is how to combine interface inheritance with implementation inheritance in C++. I would suggest using template class for window implementation.
// Window interface
class LWindow
{
};
// ListBox interface (inherits Window interface)
class LListBox : public LWindow
{
};
// Window implementation template
template<class Interface>
class WindowImpl : public Interface
{
};
// Window implementation
typedef WindowImpl<LWindow> Window;
// ListBox implementation
// (inherits both Window implementation and Window interface)
class ListBox : public WindowImpl<LListBox>
{
};
As I remember WTL windows library is based on the similar pattern of combining interfaces and implementations. I hope it helps.
Oh man this is confusing.
OK, so L*** is a hierarchy of interfaces, that's fine. Now what are you using the p_Impl for, if you have an interface, why would you include implementation in it?
The macro stuff is of course ugly, plus it's usually impossible to do. The whole point is that you will have different implementations, if you don't, then why create several classes in the first place?
OP seems confused. Here' what to do, it is very complex but it works.
Rule 1: Design the abstractions. If you have an "is-A" relation you must use public virtual inheritance.
struct Window { .. };
struct ListBox : virtual Window { .. };
Rule 2: Make implementations, if you're implementing an abstraction you must use virtual inheritance. You are free to use inheritance to save on duplication.
class WindowImpl : virtual Window { .. };
class BasicListBoxImpl : virtual ListBox, public WindowImpl { .. };
class FancyListBoxImpl : public BasicListBoxImpl { };
Therefore you should read "virtual" to mean "isa" and other inheritance is just saving on rewriting methods.
Rule3: Try to make sure there is only one useful function in a concrete type: the constructor. This is sometimes hard, you may need some default and some set methods to fiddle things. Once the object is set up cast away the implementation. Ideally you'd do this on construction:
ListBox *p = new FancyListBoxImpl (.....);
Notes: you are not going to call any abstract methods directly on or in an implementation so private inheritance of abstract base is just fine. Your task is exclusively to define these methods, not to use them: that's for the clients of the abstractions only. Implementations of virtual methods from the bases also might just as well be private for the same reason. Inheritance for reuse will probably be public since you might want to use these methods in the derived class or from outside of it after construction to configure your object before casting away the implementation details.
Rule 4: There is a standard implementation for many abstractions, known as delegation which is one you were talking about:
struct Abstract { virtual void method()=0; };
struct AbstractImpl_Delegate: virtual Abstract {
Abstract *p;
AbstractImpl_Delegate (Abstract *q) : p(q) {}
void method () { p->method(); }
};
This is a cute implementation since it doesn't require you to know anything about the abstraction or how to implement it... :)
I found that
Using
the preprocessor #define directive to
define constants is not as precise.
[src]
Macros are apparently not as precise, I did not even know that...
The classic hidden dangers of the preprocessor like:
#define PI_PLUS_ONE (3.14 + 1)`
By doing so, you avoid the possibility
that an order of operations issue will
destroy the meaning of your constant:
x = PI_PLUS_ONE * 5;`
Without
parentheses, the above would be
converted to
x = 3.14 + 1 * 5;
[src]