Suppose I have a simple interface with two methods:
class iface {
public:
virtual void foo() = 0;
virtual void bar() = 0;
};
Now I want to define a large number of implementations of that interface, but the only difference in the class declarations will be the names. So, that means no extra methods, variables or other protected expressions.
For example:
class bar1 : public iface {
public:
void foo();
void bar();
};
class bar2 : public iface {
public:
void foo();
void bar();
};
Etc, up to barN where N could be about 50-60 classes.
Obviously the implementations are all going to be different, but there's still the problem of a ton of boilerplate definitions going on in the header. I'd like to be able to somehow avoid defining these classes over and over again if possible. I was thinking that perhaps I could use macros or templates to automate the generation so I can just type the next class in the list bar3 into a function that would generate code that could be compiled and linked against. However, I was reading and I guess it's not recommended to macro class definitions for debugging purposes. Templates intuitively feel like a possible solution, but I still have to define the template somewhere.
If your problem is really this simple (i.e., was not over-simplified), then you might just do something like:
template<int i,
typename std::enable_if_t< (i >= 0 && i < 50) > // this line is very much optional
>
class bar : public iface {
public:
void foo();
void bar();
};
I'd also suggest to mark foo() and bar() with virtual and/or override everywhere. If you want to simplify implementations as well, then you might first delegate (from the virtual override) to a template function, but some additional info would be useful to elaborate on that further.
Related
I have a embedded C++03 codebase that needs to support different vendors of gadgets, but only ever one at a time. Most of the functions overlap between the several gadgets, but there are a few exclusives, and these exclusive functions are creating a problem that I need to solve.
Here is an example of clumsy code that works using pre-processor conditionals:
#define HW_TYPE1 0
#define HW_TYPE2 1
#define HW_TYPE HW_TYPE1
struct GadgetBase {
void FncA();
// Many common methods and functions
void FncZ();
};
#if HW_TYPE==HW_TYPE2
struct Gadget : public GadgetBase {
bool Bar() {return(true);}
};
#else
struct Gadget : public GadgetBase {
bool Foo() {return(false);}
};
#endif
Gadget A;
#if HW_TYPE==HW_TYPE2
bool Test() {return(A.Bar());}
#else
bool Test() {return(A.Foo());}
Here is my attempt at converting the above code to C++ templates without pre-processor directives.
The following code does not compile due to an error in the definition of Test() on my particular platform, because either Foo() or Bar() is undefined depending on the value of Type.
enum TypeE {
eType1,
eType2
};
const TypeE Type= eType1; // Set Global Type
// Common functions for both Gadgets
struct GadgetBase {
void FncA();
// Many common methods and functions
void FncZ();
};
// Unique functions for each gadget
template<TypeE E= eType1>
struct Gadget : public GadgetBase {
bool Foo() {return(false);}
};
template<>
struct Gadget<eType2> : public GadgetBase {
bool Bar() {return(true);}
};
Gadget<Type> A;
template<TypeE E= eType1>
bool Test() {return(A.Foo());}
template<>
bool Test() {return(A.Bar());}
I want to do this with templates to keep the number of code changes down when a new type or additional functions are added. There are currently five types with at least two more expected soon. The pre-processor implementation code reeks, I want to clean this up before it gets unwieldy.
The gadget code is a small amount of the total code base, so breaking up the entire project per gadget may not be ideal either.
Even though only one type will ever be used for each project, the unused types still have to compile, how do I best design this using C++03 (no constexpr, const if, etc)? Am I completely approaching this wrongly? I am willing to do a complete overhaul.
EDIT:
Tomek's solution below makes me wonder if it violates LSP. Effectively, another way to look at this is having Test() be part of an interface that requires implementation. So, the example can be reconsidered like the following:
struct GadgetI {
virtual bool Test()=0;
};
template<TypeE E= eType1>
struct Gadget : public GadgetBase, public GadgetI {
bool Foo() {return(false);}
bool Test() {return Foo();}
};
template<>
struct Gadget<eType2> : public GadgetBase, public GadgetI {
bool Bar() {return(true);}
bool Test() {return Bar();}
};
template<>
struct Gadget<eType3> : public GadgetBase, public GadgetI {
bool Test() {} // Violation of LSP?
};
Or similarly with the edited example:
template<typename T>
bool Test(T& o) {} // Violation?
template<>
bool Test(Gadget<eType1> &o) {return(o.Foo());}
template<>
bool Test(Gadget<eType2> &o) {return(o.Bar());}
Test(A);
I might be over-thinking this, I just don't want a poor design now to bite me later.
I agree the code looks convoluted, I'm with you there. But I believe you are going in the wrong direction. Templates seem cool but they are not the right tool in this case. With templates you WILL always compile all the options every time, even if they are not used.
You want the opposite. You want to ONLY compile one source at a time. The proper way to have the best of both worlds is to separate each implementation in a different file and then pick which file to include/compile using external methods.
Build systems usually have plenty of tools for this respect. For example, for compiling natively, we can rely on CMAKE's own CMAKE_SYSTEM_PROCESSOR to identify which is the current processor.
If you want to cross compile you need to specify which platform you want to compile to.
Case in mind, I have a software that needs to be compiled in many operating systems like Redhat, CentOS, Ubuntu, Suse and Windows/Mingw. I have one bash script file that checks for the environment and loads a toolchain cmake file specific for that operating system.
Your case seems to be even simpler. You could just indicate which platform you'd like to use and instruct the build system to compile just the file specific to that platform.
You are getting there :).
Rewrite your Test function so it doesn't rely on global Gadget object but instead takes one as a templated parameter:
template<class T>
bool Test(T &o, std::integral_constant<bool (T::*)(), &T::Foo> * = 0)
{
return(o.Foo());
}
template<class T>
bool Test(T &o, std::integral_constant<bool (T::*)(), &T::Bar> * = 0)
{
return(o.Bar());
}
And call it as:
Test(A);
This relies on SFINAE (Substitution Failure Is Not An Error) idiom. Based on the definitions compiler will deduce the type of T to be a Gadget. Now, depending on availability of the Foo and Bar function it will pick one of the overloads.
Please note this code WILL BREAK if both Foo and Bar are defined in Gadget as the two overloads will match.
This brings a question if you just can't wrap calls to Foo and Bar inside a Gadget class:
template<TypeE E= eType1>
struct Gadget : public GadgetBase {
bool Foo() {return(false);}
bool Test() {return Foo();}
};
template<>
struct Gadget<eType2> : public GadgetBase {
bool Bar() {return(true);}
bool Test() {return Bar();}
};
and consistently call A.Test() instead?
EDIT:
I might have over-complicated it. The following overload may be an easier approach to this:
bool Test(Gadget<eType1> &o)
{
return(o.Foo());
}
bool Test(Gadget<eType2> &o)
{
return(o.Bar());
}
Test(A);
If a class has lots of private functions it seems undesirable to have them declared in the header file. It makes it harder for clients to parse the interface of the class and it increases compilation time.
One option is, of course, the pimpl idiom, but that adds a layer of indirection and also results in a memory allocation.
What follows is a example of hiding helper functions in a friend class that is defined in the implementation file.
Is there a name for this idiom?
Is there any reason not to do it?
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
int x;
// more data...
friend struct FooHelpers;
};
//Foo.cpp
struct FooHelpers
{
static void Helper1(Foo& f)
{
// manipulate private data..
f.x++; //etc.
}
// Possibly more funcs...
};
void Foo::FuncA()
{
//....
FooHelpers::Helper1(*this);
//....
}
//....
Is there a name for the idiom of using a friend class to hide what would have been private functions?
The Attorney-Client idiom.
Is there any reason not to do it?
As suggested also in some comments, here's a reason not to do it: while it provides a patterned option, it avoids dealing with the root of the problem - the design of the original class (class Foo).
In your question you write:
If a class has lots of private functions it seems undesirable to have them declared in the header file.
There's some subjectivity to this question so allow me to restate it more objectively with the following question.
Are there ways to avoid private member functions?
You pointed out one way, to use the PIMPL idiom. As also suggested in some comments, here's some more:
Refactor the original (a.k.a. client) class to instead use non-member non-friend functions or lambda expressions that manipulate your class member data through parameters - so that it doesn't need private member functions.
Split up the class into multiple smaller classes so that each of the smaller classes declares less of the original class's private member functions. Like with member data, the more private member functions a class has, the more likely - at least in my opinion - the class is violating the single responsibility principal. So this kind of effort can reduce the private member functions as well making your class design more robust.
Say we start with the following code:
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
void multiplyByTwo();
int x;
// more data...
};
//Foo.cpp
void Foo::multiplyByTwo()
{
x = x * 2;
}
void Foo::FuncA()
{
multiplyByTwo();
}
Here's an example using the first way of what this could be changed to:
//Foo.h
class Foo
{
public:
void FuncA();
void FuncB();
private:
int x;
// more data...
};
//Foo.cpp
namespace {
int multiplyByTwo(int x)
{
return x * 2;
}
}
void Foo::FuncA()
{
x = multiplyByTwo(x);
}
In addition to eliminating the declaration of multiplyByTwo as a private member function of class Foo, this change also more idiomatically expresses the intention of the multiplyByTwo function in now saying in C++ syntax what's its input and output.
I want to test some code that is written to run on an embedded processor in a Visual Studio Native Unit Test project.
The TestMe class has several methods that are good candidates for testing, but the Foo and Bar classes directly access memory mapped registers that are only available on the embedded processor.
#pragma once
#include "Foo.h"
#include "Bar.h"
class TestMe
{
public:
TestMe(Foo& aFoo, Bar& aBar);
~TestMe();
float FooBar();
};
What is the best way to mock away these objects so that I can test the TestMe class?
Edit: For me the best way would be the one that interferes as little as possible with the software that is being tested.
"Best" is always subjective, but I like using templates for this kind of mocking:
template <typename TFoo, typename TBar>
class TestMeImpl
{
public:
TestMeImpl(TFoo& aFoo, TBar& aBar);
~TestMeImpl();
float FooBar();
};
using TestMe = TestMeImpl<Foo, Bar>;
You would write unit tests against TestMeImpl, but expose TestMe to your users.
Your Foo and Bar are passed to constructor by reference.
There are two approaches to this.
My personal favor is to use interface and leverage polymorphic objects.
So it looks like this:
class IFoo {
public:
virtual void someFunction() = 0;
};
class IBar {
public:
virtual void otherFunction() = 0;
};
class Foo : public IFoo {
....
void someFunction() {
}
};
class Bar : public IBar {
.....
void otherFunction() {
}
};
class TestMe {
public:
TestMe(IFoo& aFoo, IBar& aBar);
~TestMe();
float FooBar();
};
// test code (GMock example):
class MockFoo : public IFoo {
MOCK_METHOD(someFunction(), void());
};
class MockBar : public IBar {
MOCK_METHOD(otherFunction(), void());
};
TEST(TestMeTest, someTest)
{
MockBar bar;
MockFoo foo;
TestMe testMe(bar, foo);
EXPECT_CALL(bar, otherFunction());
EXPECT_EQ(0.2, testMe.FooBar());
}
This is basically same thing as use of templates. In this case dynamic polymorphism is used.
In case of template you got something similar so some people call it static polymorphism.
Both approaches have pros and cons and it is your decision which one is best in your case.
There is a solution to not introduce interfaces only for testing purposes (:
Link time substitution.
Rules:
Foo and Bar are in a static lib (there can be separate libs for Foo and Bar)
Don't link these libs to test exec.
Create a mock implementation that will be linked to test exec:
Hpp file:
#pragma once
#include <gmock/gmock.h>
class FooMock
{
FooMock();
~FooMock();
MOCK_METHOD0(foo, void());
};
Cpp file:
#include "Foo.hpp"
#include "FooMock.hpp"
namespace
{
FooMock* fooMock;
}
FooMock::FooMock()
{
assert(!fooMock);
fooMock = this;
}
FooMock::~FooMock()
{
fooMock = nullptr;
}
// Implement real Foo::foo
void Foo::foo()
{
// call FooMock::foo
fooMock->foo();
}
Disadvantage is that it won't work for multithread tests.
Hope it helps.
Depending on the size and performance constraints of the embedded platform introducing interfaces for the sole purpose of unit testing can be a bad idea. For small systems I favor the approach of type-aliasing classes which represent some kind of processor peripheral. I guess that's also what "Foo" and "Bar" in your example represent.
The right type alias for the current target can be chosen by using architecture predefines
struct Uart1 {};
struct Uart1Mock {};
#ifdef __x86_64__
using SensorUart = Uart1Mock;
#else
using SensorUart = Uart1;
#endif
The application code then simply uses SensorUart, no matter if the class depends on an actual serial port or simply uses standard io.
I am writing a shared library (call it MyLib) which depends on another library (call it ParentLib). The ParentLib has a few virtual functions which I am implementing in MyLib along with several other independent implementations.
// MyLib.h
#include <parentlib_library.h>
class Foo : public ClassinParent
{
public:
void DefinitionofParentLibFunction();
private:
// ...
};
I was able to compile and generate the MyLib with no issues but when the MyLib is used by the application, I need to include the ParentLib_library.h to compile the code.
One of my requirements is that the ParentLib should be completely hidden from the application. I am not sure of the next step to achieve this.
Any ideas?
If your declaration used in callback or implementation of interface from 3dparty lib - then no way. In all another cases I usually apply following 3 approaches.
1) Use aggregation. Declare ClassInParent as forward and use as member of Foo:
class ClassInParent;//forward declare
class Foo
{
ClassInParent* _inst; //use either pointer of reference to external
public:
void method_of_ClassInParent() //make facade for parent methods if needed
}
2) Separate your class into interface (that is not depended on ClassInParent) and implementation (that is not expose via #include)
Your Foo.h:
class Foo
{
public:
virtual void do_smth() = 0;
};
Your Foo.cpp:
#include <parentlib_library.h>
class FooImpl : public Foo, public ClassInParent
{
void do_smth()
{//implementation
3) Use templates. Instead of explicit inherience use template:
template <class T>
class Foo : public T
{
Later in your code Foo<ClassInParent>
I want to use the pimpl idiom to avoid having users of my library need our external dependencies (like boost, etc) however when my class is templated that seems to be impossible because the methods must be in the header. Is there something I can do instead?
If the class is templated, your users essentially need to compile it (and this is literally true in the most widely-used C++ implementations) and so they need your external dependencies.
The simplest solution is to put the bulk of your class's implementation in a non-template base class (or encapsulated member object of some class). Solve the module-hiding problem there.
And then write the template derived (or enclosing) class to add type safety to it.
For example, suppose you have a template that provides the amazing ability to allocate on first access (omitting the necessary copy constructor, assignment, destructor):
template <class T>
class MyContainer
{
T *instance_;
public:
MyContainer() : instance_(0) {}
T &access()
{
if (instance_ == 0)
instance_ = new T();
return *instance_;
}
};
If you wanted the "logic" to be separated into a non-template base class, you'd have to parameterise the behaviour in the non-template way, which is to say, use virtual functions:
class MyBase
{
void *instance_;
virtual void *allocate() = 0;
public:
MyBase() : instance_(0) {}
void *access()
{
if (instance_ == 0)
instance_ = allocate();
return instance_;
}
};
Then you can add the type-awareness in the outer layer:
template <class T>
class MyContainer : MyBase
{
virtual void *allocate()
{ return new T(); }
public:
T &access()
{ return *(reinterpret_cast<T *>(MyBase::access())); }
};
i.e. You use virtual functions to allow the template to "fill in" the type-dependent operations. Obviously this pattern would only really make sense if you have some business logic that is worth the effort of hiding.
You can explicitly instantiate templates in the source file, but that is possible only if you know what the template type is going to be. Otherwise, do not use pimpl idiom for templates.
Something like this :
header.hpp :
#ifndef HEADER_HPP
#define HEADER_HPP
template< typename T >
class A
{
// constructor+methods + pimpl
};
#endif
source.cpp :
#include "header.hpp"
// implementation
// explicitly instantiate for types that will be used
template class A< int >;
template class A< float >;
// etc...
There are two general solutions:
while the interface depends on some type T, it defers to a more weakly typed implementation (e.g. one using void* pointers directly or trough type erasure), or
you support only a specific and quite limited number of types.
The second solution is relevant for e.g. char/wchar_t-dependent stuff.
The first solution was quite common in the early days of C++ templates, because at that time compilers were not good at recognizing commonalities in the generated machine code, and would introduce so called “code bloat”. Today, much to the surprise of any novice who tries it out, a templated solution can often have smaller machine code footprint than a solution relying on runtime polymorphism. Of course, YMMV.
Cheers & hth.,