Case 1
Here we consider:
Foo foo{2}; //this will create an object of type `Foo` on the stack
The above statement will create an object of type Foo on the stack using the converting constructor Foo::Foo(int).
Case 2
Here we consider:
Foo *foo2;           //creates a pointer of type `Foo*` on the stack
foo2 = new Foo(2);   //assign foo2 the pointer returned from new Foo(2)
Here first we create a pointer named foo2 of type Foo* on the stack. Note that as of now this pointer is uninitialized.
Next, when we write foo2 = new Foo(2); the following things happen:
- Due to - new Foo(2)an object of type- Foois created on the heap using the converting constructor- Foo::Foo(int).
 
- Next, a pointer to that dynamically allocated object is returned. 
- This returned pointer is assigned to - foo2on the left hand side.
 
Note also that instead of assigning i to j  inside the constructor you can instead initialize j in the constructor initializer list as shown below:
Class Foo {
public:
    int j;
//--------------vvvv--------------> initialize j in the member initializer list
    Foo(int i): j(i){
       
        std::cout << j << endl;
    };
}