Note: This is a complete re-wording of a question I posted a while ago. If you find they are duplicate, please close the other one.
My problem is quite general but it seems that it could be explained more easily based on a concrete simple example. So imagine I want to simulate the electricity consumption in an office throught time. Let's assume that there is only a light and heating.
class Simulation {
    public:
        Simulation(Time const& t, double lightMaxPower, double heatingMaxPower)
            : time(t)
            , light(&time,lightMaxPower) 
            , heating(&time,heatingMaxPower) {}
    private:
        Time time; // Note : stack-allocated
        Light light;
        Heating heating;
};
class Light {
    public:
        Light(Time const* time, double lightMaxPower)
            : timePtr(time)
            , lightMaxPower(lightMaxPower) {}
        bool isOn() const {
            if (timePtr->isNight()) {
                return true;
            } else {
                return false;
            }
        }
        double power() const {
            if (isOn()) {
                return lightMaxPower;
            } else {
                return 0.;
            }
    private:
        Time const* timePtr; // Note : non-owning pointer
        double lightMaxPower;
};
// Same kind of stuff for Heating
The important points are:
1.Time cannot be moved to be a data member Light or Heating since its change does not come from any of these classes.
2.Time does not have to be explicitly passed as a parameter to Light. Indeed, there could be a reference to Light in any part of the program that does not want to provide Time as a parameter.
class SimulationBuilder {
    public:
        Simulation build() {
            Time time("2015/01/01-12:34:56");
            double lightMaxPower = 42.;
            double heatingMaxPower = 43.;
            return Simulation(time,lightMaxPower,heatingMaxPower);
        }
};
int main() {
    SimulationBuilder builder;
    auto simulation = builder.build();
    WeaklyRelatedPartOfTheProgram lightConsumptionReport;
    lightConsumptionReport.editReport((simulation.getLight())); // No need to supply Time information 
    return 0;
}
Now, Simulation is perfectly find as long as it is not copy/move constructed. Because if it is, Light will also get copy/move constructed and by default, the pointer to Time will be pointing to the Time in the old Simulation instance which is copied/moved from.
However, Simulation actually is copy/move constructed in between the return statement in SimulationBuilder::build() and the object creation in main()
Now there are a number of ways to solve the problem:
1: Rely on copy elision. In this case (and in my real code) copy elision seems to be allowed by the standard. But not required, and as a matter of fact, it is not elided by clang -O3. To be more precise, clang elides Simulation copy, but does call the move ctor for Light. Also notice that relying on an implementation-dependent time is not robust.
2: Define a move-ctor in Simulation:
Simulation::Simulation(Simulation&& old) 
    : time(old.time)
    , light(old.light)
    , heating(old.heating)
{
    light.resetTimePtr(&time);
    heating.resetTimePtr(&time);
}
Light::resetTimePtr(Time const* t) {
    timePtr = t;
}
This does work but the big problem here is that it weakens encapsulation: now Simulation has to know that Light needs more info during a move. In this simplified example, this is not too bad, but imagine timePtr is not directly in Light but in one of its sub-sub-sub-member. Then I would have to write
Simulation::Simulation(Simulation&& old) 
    : time(old.time)
    , subStruct(old.subStruct)
{
    subStruct.getSubMember().getSubMember().getSubMember().resetTimePtr(&time);
}
which completly breaks encapsulation and the law of Demeter. Even when delegating functions I find it horrible.
3: Use some kind of observer pattern where Time is being observed by Light and sends a message when it is copy/move constructed so that Light change its pointer when receiving the message.
I must confess I am lazy to write a complete example of it but I think it will be so heavy I am not sure the added complexity worth it.
4: Use a owning pointer in Simulation:
class Simulation {
    private:
        std::unique_ptr<Time> const time; // Note : heap-allocated
};
Now when Simulation is moved, the Time memory is not, so the pointer in Light is not invalidated. Actually this is what almost every other object-oriented language does since all objects are created on the heap.
For now, I favor this solution, but still think it is not perfect: heap-allocation could by slow, but more importantly it simply does not seems idiomatic. I've heard B. Stroustrup say that you should not use a pointer when not needed and needed meant more or less polymorphic. 
5: Construct Simulation in-place, without it being return by SimulationBuilder (Then copy/move ctor/assignment in Simulation can then all be deleted). For instance
class Simulation {
    public:
        Simulation(SimulationBuilder const& builder) {
            builder.build(*this);
        }
    private:
        Time time; // Note : stack-allocated
        Light light;
        Heating heating;
        ...
};
class SimulationBuilder {
    public:
        void build(Simulation& simulation) {
            simulation.time("2015/01/01-12:34:56");
            simulation.lightMaxPower = 42.;
            simulation.heatingMaxPower = 43.;
    }
};
Now my questions are the following:
1: What solution would you use? Do you think of another one?
2: Do you think there is something wrong in the original design? What would you do to fix it?
3: Did you ever came across this kind of pattern? I find it rather common throughout my code. Generally though, this is not a problem since Time is indeed polymorphic and hence heap-allocated.
4: Coming back to the root of the problem, which is "There is no need to move, I only want an unmovable object to be created in-place, but the compiler won't allow me to do so" why is there no simple solution in C++ and is there a solution in another language ?
 
     
     
     
     
    