The second example, @State var valueClass = VC() is not typically, or ever done. The "state" being created is the result of creating an object by VC() which is a reference (or pointer) to a VC object. It's a memory address and it won't change, even if the properties it holds do change. Since there's no change to it, the view doesn't update.
Your third example @ObservedObject var valueClassObserved = VD() is also problematic and not typically done. ObservedObjects are intended to observe changes within objects not owned by the view. Here the object is being created and owned by the view.
What you are looking for is either the first example, just using a @State and value type or @StateObject if you want to track an object that you create in the view. So in your example just change ObservedObject to StateObject. StateObject is intended to keep track of objects that are created and owned by the view.
To summarize: If you are initializing the object inside your View code, use @StateObject. If it's initialized outside your View code, and you pass it as argument or otherwise, use @ObservedObject (or @EnvironmentObject, which is more convenient in global cases)