I'm trying to build a shared library in C++ in Ubuntu (which I will load at runtime using dlopen), but I noticed that the shared library builds just fine even if there's some missing dependencies. If I were to build an executable I would get an undefined reference linker error, which is what I would like to see here. 
There might be a little too much detail in this example, but I wasn't entirely sure how to pare it down and also make it representative.
Base.h
class Base{
 public:
 virtual void foo()=0;
};
extern "C" {
Base* CreateBase();
}
extern "C" {
void DestroyBase(Base* b);
}
Derived.h
#include "Base.h"
class Derived : public Base {
 public:
 void foo();
};
extern "C" {
Base* CreateBase() {
   return new Derived;
}
}
extern "C" {
void DestroyBase(Base* b) {
   delete b;
}
}
Derived.cc
#include "Derived.h"
#include "OtherClass.h"
#include <iostream>
void Derived::foo(){
  std::cout << "Derived::foo()" << std::endl;
  std::cout << "Calling OtherClass::bar()" << std::endl;
  OtherClass other;
  other.bar();
}
OtherClass.h
class OtherClass{
  public:
  void bar();
};
My command line to build the shared library is
g++ -shared -fPIC -o libtest_dll.so Derived.cc
The problem is that I have no definition of OtherClass::bar() which is called by Derived::foo(), but libtest_dll.so builds without error or warning. It's my understanding that in Visual Studio in Windows if I were to build a DLL out of this code, it would fail to link. How can I get that behavior using g++ in Ubuntu/Linux?
Running g++ 8.3.0-6 on Ubuntu 19.04