I'm writing for a project that uses makefile rules to switch between GPU and CPU implementations. I'd like to present an interface to user code that automatically switches between implementations without having to write #ifdef GPU_MODE all over the place.
My solution had been to use a templated interface class followed by alias templates (just typedefs, really, but I like the left-to-right style) like so:
namespace INTERFACE{
template <class VERSION>
class MyClass{
public:
MyClass():theClass(){};
//more methods...
private:
VERSION theClass;
};
}
using CpuMyClass = INTERFACE::MyClass<CpuMode>; //CpuMode defined elsewhere
#ifdef GPU_MODE
using MyClass = INTERFACE::MyClass<GpuMode>;
#else
using MyClass = INTERFACE::MyClass<CpuMode>;
#endif
Thus allowing outside code to use the symbol MyClass freely, trusting it to switch between modes automatically. Unfortunately using this is proving confusing. For example, I have a second class for which I'd like to write a ctor from MyClass:
#include "MyClass.hpp"
class OutsideClass{
public:
OutsideClass(const MyClass& A);
};
This ctor triggers an "identifier 'MyClass' is undefined" error. Does anyone know what's going on here?
Did you mean something like:
struct GpuMode { };
struct CpuMode { };
namespace INTERFACE {
// ~~~~~~~~^^^^^^
template <class VERSION>
class MyClass{
public:
MyClass() : theClass(){};
//more methods..
private:
VERSION theClass;
};
}
using CpuMyClass = INTERFACE::MyClass<CpuMode>; //CpuMode defined elsewhere
#ifdef GPU_MODE
using MyClass = INTERFACE::MyClass<GpuMode>;
#else
using MyClass = INTERFACE::MyClass<CpuMode>;
#endif
class OutsideClass{
public:
OutsideClass(const MyClass& A);
};
Demo
Related
We have a heavily-templated header-only codebase that a client would like access to. For example, let's say it contains the Foo class in the header foo.hpp:
#ifndef FOO_HEADER
#define FOO_HEADER
#include <iostream>
template <typename T>
struct Foo {
Foo(){
// Do a bunch of expensive initialization
}
void bar(T t){
std::cout << t;
}
// Members to initialize go here...
};
#endif /* FOO_HEADER */
Now we want to let the client try a reduced set of the functionality without exposing the core code and without rewriting the whole codebase.
One idea would be to use the PIMPL idiom to wrap this core code. Specifically, we could create a FooWrapper class with the header foo_wrapper.hpp:
#ifndef FOO_WRAPPER_HEADER
#define FOO_WRAPPER_HEADER
#include <memory>
struct FooWrapper {
FooWrapper();
~FooWrapper();
void bar(double t);
private:
struct Impl;
std::unique_ptr<Impl> impl;
};
#endif /* FOO_WRAPPER_HEADER */
and implementation foo_wrapper.cpp:
#include "foo.hpp"
#include "foo_wrapper.hpp"
struct FooWrapper::Impl {
Foo<double> genie;
};
void FooWrapper::bar(double t){
impl->genie.bar(t);
}
FooWrapper::FooWrapper() : impl(new Impl){
}
FooWrapper::~FooWrapper() = default;
This code works as I expect it: https://wandbox.org/permlink/gso7mbe0UEOOPG7j
However, there is one little nagging thing that is bothering me. Specifically, the implementation requires what feels like an additional level of indirection... We have to define the Impl class to hold a member of the Foo class. Because of this, all of the operations have this indirection of the form impl->genie.bar(t);.
It would be better if we could somehow tell the compiler, "Actually Impl IS the class Foo<double>", in which case, we could instead say impl->bar(t);.
Specifically, I am thinking something along the lines of typedef or using to get this to work. Something like
using FooWrapper::Impl = Foo<double>;
But this does not compile. So on to the questions:
Is there a nice way to get rid of this indirection?
Is there a better idiom I should be using?
I am targeting a C++11 solution, but C++14 may work as well. The important thing to remember is that the solution can't use the header foo.hpp in foo_wrapper.hpp. Somehow we have to compile that code into a library and distribute just the compiled library and the foo_wrapper header.
You can just forward-declare Foo in FooWrapper.h. This will allow you to declare a std::unique_ptr for it:
#ifndef FOO_WRAPPER_HEADER
#define FOO_WRAPPER_HEADER
#include <memory>
// Forward declaration
template <typename T>
class Foo;
struct FooWrapper {
FooWrapper();
~FooWrapper();
void bar(double t);
private:
std::unique_ptr<Foo<double>> impl;
};
#endif /* FOO_WRAPPER_HEADER */
foo_wrapper.cc:
#include "foo_wrapper.h"
#include "foo.h"
void FooWrapper::bar(double t) {
impl->bar(t);
}
FooWrapper::FooWrapper() : impl(std::make_unique<Foo<double>>()) {}
FooWrapper::~FooWrapper() = default;
Just use Foo<double>:
// forward declaration so that you don't need to include "Foo.hpp"
template class Foo<double>;
struct FooWrapper {
//...
std::unique_ptr<Foo<double>> impl;
};
// explicit template instantiation so that Foo<double> exists without distributing "Foo.hpp"
template class Foo<double>;
void FooWrapper::bar(double t){
impl->bar(t);
}
Is it possible to get return type UglyIterator<> of a function of a class B::f which is forward declaration?
Example
MyArray is a class that acts like std::vector.
Its begin() and end() function return a ugly type.
template<class T> class MyArray{
UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra> begin(){
//some code
}
//... other functions ....
};
B has MyArray<int> as a value field.
With the magic of auto-keyword, B can pretend to be a neat class.
#include "MyArray.h"
class B{ //just a bundle of data
MyArray<int> bField;
public: auto f(){ //<--- neat
return bField.begin();
}
//... other fields ...
};
Manager is a manager of B and do other things.
#include "B.h"
class Manager{ //just a bundle of data
decltype(&B::f) mField; //I can cache it, so neat!
//^ actually it is "UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra>"
//... other functions/fields ...
};
As project grow, I noticed that Manager.h was included in many files, and MyArray's code changed very often.
To reduce compile time, I decided to forward declaration at Manager.
I changed mField to mFieldPtr, but I get compile error :-
class B;
class Manager{
std::unique_ptr<std::result_of<decltype(&B::f)>::type> mFieldPtr;
//^ should compile error (can not recognize "B::f")
//... other functions ...
};
How to get the return type decltype(&B::f) elegantly?
My workaround
Create a new file B_TopHeader.h.
using B_F_returnType = UglyIterator<Protocol1,Protocol2,SafetyFlag,brabrabra>;
//^ the type "UglyIterator" also need another forward declaration
Then let the Manager #include B_TopHeader.h instead :-
#include "B_TopHeader.h"
class Manager{
std::unique_ptr< B_F_returnType > mFieldPtr;
//... other functions ...
};
However, I think it is not elegant. It seems to be a hack.
I have to forward the return type manually.
You may use Pimpl idiom to hide the dependency, something like:
class Manager
{
public:
~Manager() noexcept; // you certainly have also to handle copy/move
// Stuff using mFieldPtr, but which doesn't return it.
private:
std::unique_ptr<struct Impl> mImpl;
};
And in cpp
#include "Manager.h"
#include "B.h"
struct Manager::Impl
{
// Implementation using mField
decltype(&B::f) mField;
};
Manager::~Manager() noexcept = default;
// Forward methods of `Manager` to `Impl`.
There is no feature that control visibility/accessibility of class in C++.
Is there any way to fake it?
Are there any macro/template/magic of C++ that can simulate the closest behavior?
Here is the situation
Util.h (library)
class Util{
//note: by design, this Util is useful only for B and C
//Other classes should not even see "Util"
public: static void calculate(); //implementation in Util.cpp
};
B.h (library)
#include "Util.h"
class B{ /* ... complex thing */ };
C.h (library)
#include "Util.h"
class C{ /* ... complex thing */ };
D.h (user)
#include "B.h" //<--- Purpose of #include is to access "B", but not "Util"
class D{
public: static void a(){
Util::calculate(); //<--- should compile error
//When ctrl+space, I should not see "Util" as a choice.
}
};
My poor solution
Make all member of Util to be private, then declare :-
friend class B;
friend class C;
(Edit: Thank A.S.H for "no forward declaration needed here".)
Disadvantage :-
It is a modifying Util to somehow recognize B and C.
It doesn't make sense in my opinion.
Now B and C can access every member of Util, break any private access guard.
There is a way to enable friend for only some members but it is not so cute, and unusable for this case.
D just can't use Util, but can still see it.
Util is still a choice when use auto-complete (e.g. ctrl+space) in D.h.
(Edit) Note: It is all about convenience for coding; to prevent some bug or bad usage / better auto-completion / better encapsulation. This is not about anti-hacking, or prevent unauthorized access to the function.
(Edit, accepted):
Sadly, I can accept only one solution, so I subjectively picked the one that requires less work and provide much flexibility.
To future readers, Preet Kukreti (& texasbruce in comment) and Shmuel H. (& A.S.H is comment) has also provided good solutions that worth reading.
I think that the best way is not to include Util.h in a public header at all.
To do that, #include "Util.h" only in the implementation cpp file:
Lib.cpp:
#include "Util.h"
void A::publicFunction()
{
Util::calculate();
}
By doing that, you make sure that changing Util.h would make a difference only in your library files and not in the library's users.
The problem with this approach is that would not be able to use Util in your public headers (A.h, B.h). forward-declaration might be a partial solution for this problem:
// Forward declare Util:
class Util;
class A {
private:
// OK;
Util *mUtil;
// ill-formed: Util is an incomplete type
Util mUtil;
}
One possible solution would be to shove Util into a namespace, and typedef it inside the B and C classes:
namespace util_namespace {
class Util{
public:
static void calculate(); //implementation in Util.cpp
};
};
class B {
typedef util_namespace::Util Util;
public:
void foo()
{
Util::calculate(); // Works
}
};
class C {
typedef util_namespace::Util Util;
public:
void foo()
{
Util::calculate(); // Works
}
};
class D {
public:
void foo()
{
Util::calculate(); // This will fail.
}
};
If the Util class is implemented in util.cpp, this would require wrapping it inside a namespace util_namespace { ... }. As far as B and C are concerned, their implementation can refer to a class named Util, and nobody would be the wiser. Without the enabling typedef, D will not find a class by that name.
One way to do this is by friending a single intermediary class whose sole purpose is to provide an access interface to the underlying functionality. This requires a bit of boilerplate. Then A and B are subclasses and hence are able to use the access interface, but not anything directly in Utils:
class Util
{
private:
// private everything.
static int utilFunc1(int arg) { return arg + 1; }
static int utilFunc2(int arg) { return arg + 2; }
friend class UtilAccess;
};
class UtilAccess
{
protected:
int doUtilFunc1(int arg) { return Util::utilFunc1(arg); }
int doUtilFunc2(int arg) { return Util::utilFunc2(arg); }
};
class A : private UtilAccess
{
public:
int doA(int arg) { return doUtilFunc1(arg); }
};
class B : private UtilAccess
{
public:
int doB(int arg) { return doUtilFunc2(arg); }
};
int main()
{
A a;
const int x = a.doA(0); // 1
B b;
const int y = b.doB(0); // 2
return 0;
}
Neither A or B have access to Util directly. Client code cannot call UtilAccess members via A or B instances either. Adding an extra class C that uses the current Util functionality will not require modification to the Util or UtilAccess code.
It means that you have tighter control of Util (especially if it is stateful), keeping the code easier to reason about since all access is via a prescribed interface, instead of giving direct/accidental access to anonymous code (e.g. A and B).
This requires boilerplate and doesn't automatically propagate changes from Util, however it is a safer pattern than direct friendship.
If you do not want to have to subclass, and you are happy to have UtilAccess change for every using class, you could make the following modifications:
class UtilAccess
{
protected:
static int doUtilFunc1(int arg) { return Util::utilFunc1(arg); }
static int doUtilFunc2(int arg) { return Util::utilFunc2(arg); }
friend class A;
friend class B;
};
class A
{
public:
int doA(int arg) { return UtilAccess::doUtilFunc1(arg); }
};
class B
{
public:
int doB(int arg) { return UtilAccess::doUtilFunc2(arg); }
};
There are also some related solutions (for tighter access control to parts of a class), one called Attorney-Client and the other called PassKey, both are discussed in this answer: clean C++ granular friend equivalent? (Answer: Attorney-Client Idiom) . In retrospect, I think the solution I have presented is a variation of the Attorney-Client idiom.
I want to create a unit test environment for our project. But I am lost about how to create mocks for members of the classes. I want to explain my question with an example.
In my older projects, we were using a mock selection mechanism which is very ugly in my opinion. Here is the elder method:
class member {
};
class member_mock_1 {
};
class member_mock_2 {
};
class parent {
#if defined UNIT_TEST_1
typedef member_t member_mock_1;
#elif defined UNIT_TEST_2
typedef member_t member_mock_2;
#else
typedef member_t member;
#endif
private:
member_t mem;
};
The first question is mocking the classes of the member object with typedefing in or out of the parent class is a proper way or not? What is the best practice? If I want to use a unit testing framework, like gtest, should I use this kind of way or is there another way to mocking members?
Note 1: If the virtual mechanism is activated, it is ok to create base classes to ease mocking, if a class is pod or something, I don't want to use this mechanism.
Note 2: I also find ugly passing the types of members as a template parameter, everything becomes template in the project. I don't want to do that. Here is an example:
template <typename M>
class parent {
private:
M mem;
};
#if defined UNIT_TEST_1
typedef parent_t parent<member_mock_1>;
#elif defined UNIT_TEST_2
typedef parent_t parent<member_mock_2>;
#else
typedef parent_t parent<member>;
#endif
Here is the method i am suggesting here:
member_mock_1.hpp
class member_mock_1 {
};
member_mock_2.hpp
class member_mock_2 {
};
mock.hpp
template <typename TYPE>
struct mock { using type = TYPE; };
#define ENABLE_MOCKING(NamE) \
using NamE ## _t = mock<NamE>::type
member_mock.hpp
#if define UNIT_TEST_1
template<>
struct mock<member> { using type = member_mock_1 };
#endif
#if define UNIT_TEST_2
template<>
struct mock<member> { using type = member_mock_2 };
#endif
member.hpp
class member {
};
ENABLE_MOCKING(member);
parent.hpp
class parent {
private:
member_t mem;
};
Method I have mentioned above works for normal classes. For template classes some extra works should be done, i think.
So as a conclusion, I am suggesting a structure for unit testing like above. May be it is unnecessary, there are some other mechanisms or ways to cover that requirement. Maybe I still reinventing the wheel :(
Please suggest a way you know for mocking members of a class.
Thanks.
Yes, You're reinventing the wheel the code looks really messy:
#if defined UNIT_TEST_1
typedef parent_t parent<member_mock_1>;
#elif defined UNIT_TEST_2
typedef parent_t parent<member_mock_2>;
#else
typedef parent_t parent<member>;
#endif
There are several tools available.
I use Typemock Isolator++ as you can mock pretty much everything without touching your production whatsoever.
One other thing, the behavior you set on a mock will be applied only in the scope of the test, so every test has an individual and independent setup.
You can access the member, even if it's private:
member* mock_member = FAKE<member>;
parent* my_parent = new parent();
ISOLATOR_SET_MEMBER(my_parent, mem, mock_member);
And easily get it:
member* get_member;
ISOLATOR_GET_MEMBER(my_parent, mem, get_member);
Also, it allows to fake abstract classes, global methods, pure virtual methods, private and protected methods, set up behaviors for it. Furthermore, access hidden data members and invoke them. Check this for more information.
I am in a similar situation to you - introducing unit tests to a legacy C++ project. To do so I have used a lot of preprocessor directives along with Google Test and Google Mock. Particularly, if I was facing to your example, I would do as follows:
#if defined UNIT_TEST
class imember
{
virtual void a_method() = 0;
};
#endif
class member
#if defined UNIT_TEST
: public imember
#endif
{
void a_method()
{
// do something
};
};
class parent {
public:
#if defined UNIT_TEST
parent(imember mem) : mem_(mem) {};
#endif
private:
#if defined UNIT_TEST
imember mem_;
#else
member mem_;
#endif
};
Now, use Google Mock to define a mock class:
class mockmember : public imember
{
public:
MOCK_METHOD0(a_method, void());
};
Mock class is now ready. Use Google Test to define your test scenarios:
class parenttest : public testing::Test
{
public:
parenttest() : member_(mockmember()), parent_(member_) {}
virtual void SetUp() {}
virtual void TearDown() {}
protected:
parent parent_;
mockmember member_;
};
TEST_F(parenttest, a_func)
{
EXPECT_CALL(member_, a_method());
int ret = parent_.a_func();
ASSERT_EQ(0, ret);
}
Disclaimer, i work in Typemock.
Sam is totally right.
Also, you don't need to create 3 different member_mock classes for every single unit-test.
You can simply set up the behavior, for example, for some private method in member:
member* mock_member = FAKE<member>;
PRIVATE_WHEN_CALLED(member, somePrivateMethod()).Return(0);
Next using PRIVATE_WHEN_CALLED(mock_member, somePrivateMethod()) will overload behavior for somePrivateMethod(), so, instead of creating huge amount of different mock-classes just change the behavior for you needs.
Hope it'll be useful for you!
I'm writing a C++ wrapper library around a number of different hardware libraries for embedded systems (firmware level), using various libraries from different vendors (C or C++). The API exposed by the header files should be vendor agnostic... all Vendor header libraries are not included in any of my header files.
A common pattern I have is making the vendor member data opaque, by only using a pointer to some "unknown" vendor struct/class/typedef/pod type.
// myclass.h
class MyClass
{
...
private:
VendorThing* vendorData;
};
and implementation (note: each implementation is vendor specific; all have the same *.h file)
// myclass_for_vendor_X.cpp
#include "vendor.h"
... {
vendorData->doSomething();
or
VendorAPICall(vendorData,...);
or whatever
The problem I have is that VendorThing can be lots of different things. It could be a class, struct, type or pod. I don't know, and I don't want to care in the header file. But if you pick the wrong one, then it doesn't compile if the vendor header file is included as well as my header file. For example, if this the actual declaration of VendorThing in "vendor.h":
typedef struct { int a; int b; } VendorThing;
Then you can't just forward-declare VendorThing as class VendorThing;. I don't care about what the type of VendorThing is at all, all I want is the public interface to think of it as void * (i.e allocate space for a pointer and that is it), and the implementation think of it using the correct pointer type.
Two solutions I have come across are the "d-pointer" method found in Qt, where you add a level of indirection by replacing VendorThing a new struct VendorThingWrapper
// myclass.h
struct VendorThingWrapper;
class MyClass
{
...
private:
VendorThingWrapper* vendorDataWrapper;
};
and in your cpp file
// myclass.cpp
#include "vendor.h"
struct VendorThingWrapper {
VendorThing* vendorData;
};
... {
vendorDataWrapper->vendorData->doSomething();
}
but this adds a second pointer dereference, which is not a huge deal, but as this is targeting embedded systems, I don't want to add that overhead just because the language can't do what I want.
The other thing is just declare it void
// myclass.h
class MyClass
{
...
private:
void* vendorDataUntyped;
};
and in the implememtation
//myclass.cpp
#include "vendor.h"
#define vendorData ((VendorThing*)vendorDataUntyped)
... {
vendorData->doSomething();
}
but #define's always leave a bad taste in my mouth. There must be something better.
You can avoid the additional pointer dereference by using:
#include "vendor.h"
struct VendorThingWrapper : public VendorThing {};
Of course, at that point, it makes more sense to use the name MyClassData instead of VendorThingWrapper.
MyClass.h:
struct MyClassData;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassData* myClassData;
};
MyClass.cpp:
struct MyClassData : public VendorThing {};
MyClass::MyClass() : myClassData(new MyClassData())
{
}
MyClass::~MyClass()
{
delete myClassData;
}
Update
I was able to compile and build the following program. The unnamed struct is not a problem.
struct MyClassData;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassData* myClassData;
};
typedef struct { int a; int b; } VendorThing;
struct MyClassData : public VendorThing
{
};
MyClass::MyClass() : myClassData(new MyClassData())
{
myClassData->a = 10;
myClassData->b = 20;
}
MyClass::~MyClass()
{
delete myClassData;
}
int main() {}
If you are willing to go the route of the VendorThingWrapper, then you simply allow the wrapper to contain the data itself, rather than a pointer to it. This gives you the abstraction layer and avoids the extra dereference.
// myclass.cpp
#include "vendor.h"
struct VendorThingWrapper {
VendorThing vendorData;
};
... {
vendorDataWrapper->vendorData.doSomething();
}