#include <iostream>
#include <memory>

struct LoggerInterface {}; 

std::shared_ptr<LoggerInterface> pi = std::make_shared<LoggerInterface>(); 

struct B {
	virtual void foo(int blablabla, std::shared_ptr<LoggerInterface> logger = nullptr) = 0;
};
struct D : B {
    void foo(int blablabla, std::shared_ptr<LoggerInterface> logger) override {
    	std::cout << "foo: "<<blablabla<<" "<< logger<<std::endl; 
    }
};

struct E : B {
    void foo(int blablabla, std::shared_ptr<LoggerInterface> logger = pi) override {
    	std::cout << "foo: "<<blablabla<<" "<< logger<<std::endl; 
    }
};

int main() {
	D d; 
	B *b=&d;
	b->foo(15); 
	//d.foo(15);
	E e; 
	
	e.foo(16); 
	B *b2 = &e; 
	b2->foo(16);
	
	return 0;
}