I was experimenting with c++ 20 modules
I am trying to do the 'virtual constructor' idiom, i.e. do the following
class Base{
public:
virtual ~Interface() = default;
virtual void DoStuff() = 0;
static std::unique_ptr<Base> Create();
}
class Impl : public Base{
public:
void DoStuff() override;
}
std::unique_ptr<Base> Base::Create(){
return std::make_unique<Impl>();
}
Without modules i can place declarations of Base in base.h, declaration of Impl in impl.h, this way the clients don't see the Impl class, and both impl.cpp and base.cpp can compile.
I know with modules it is possible to keep everything in a single module, and simply do not export the Impl class. But suppose we have many different implementations classes, and each one is big and comes with its own dependencies, in this case i would like to place Interface and Impl into different modules - for better structure and readability, and to isolate dependencies.
But with modules and module partition this doesn't seem possible, because partition :base needs to import :impl (for the virtual constructor to work), and partition impl needs to import :base to be able to derive from Base.
What am i doing wrong? Or maybe i am just thinking in old terms and the solution with 1 big module is perfectly fine? (Another possible solution would be to use an ordinary function instead of a static method).
To break the dependencies you need to separate Base and Impl. I got this working in msvc with the /internalPartition
flag
//m.ixx
module;
#include "pch.h"
#include <memory>
export module m;
export
class Base {
public:
virtual ~Base() = default;
virtual void DoStuff() = 0;
static std::unique_ptr<Base> Create();
};
//m.cpp
module;
#include "pch.h"
#include <memory>
#include <iostream>
module m;
class Impl : public Base {
public:
void DoStuff() override
{
std::cout << "hello\n";
}
};
std::unique_ptr<Base> Base::Create() {
return std::make_unique<Impl>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With