To split a module into multiple files you need to use partitions. To do this you need to first create a primary interface:
export module Units;
then you declare each separate file that makes up the module as a named partition(export module <module_name>:<partition_name>) eg:
export module Units:Impl;
This does not by itself share classes, variables or functions between the files though. To access a partition from the primary interface or another partition you need to add an import statement import :<partition_name> eg:
import :Impl;
so in the code you have above Units_impl.ixx knows nothing about Base as it is declared in a separate file hence the error.
This also means you cannot declare the class Base in the primary interface if you want to have access to it from a partition as this would result in a cyclic dependancy. Ie the partition would need to import Units(the primary interface) which would itself need to import the partition(Units:Impl). So at the very least your files would need to look something like:
Units.ixx:
export module Units;
import :Impl;
export void foo();
Units_Impl.ixx:
class Base{};
class Derived: public Base{};
export void foo()
{
Derived derived;
}
Main.cpp:
import Units;
int main()
{
foo();
return 0;
}
If you didn't want Base to be in the same file as Derived you'd need to create another partition in a separate file eg:
Units_Base.ixx:
export Units:Base;
export class Base{};
and then your Units_Impl.ixx would look like this:
export Units:Impl;
import :Base;
class Derived: public Base{};
export void foo()
{
Derived derived;
}
Finally you can re-export from an imported module using export import <module_or_partition_name> eg:
export import :Impl;
this would then make export void foo(); in Units.ixx unnecessary and it would look like this:
export module Units;
export import :Impl;