The const property is not transitive, when dereferencing pointers. You access the pointer m_ptras read-only, but this pointer itself is not a pointer to const. You write to the object pointed to by m_ptr, not m_ptr itself.
You could write two getter functions instead of a public access to the m_ptr member variable. One getter function is const and returns a pointer to const, one is not const and returns a normal pointer.
class Test {
private:
    int* m_ptr;
public:
    Test(int* ptr) : m_ptr(ptr) {};
    const int* ptr() const { return m_ptr; }; // this overload is called for const Test object (const this*)
    int* ptr() { return m_ptr; }; // this overload is called for non-const Test object
};
int main()
{
    int a;
    Test x(&a);         // x is non-const
    const Test& x2 = x; // x2 is const
    int* p = x.ptr();   // okay
    *p = 3;             // okay
    int* p2 = x2.ptr(); // error: invalid conversion from 'const int*' to 'int*'
    *p2 = 4;
}
Then inside the const takeObj you can only access the const int* version of m_ptr.
Bonus info:
On C the test object (if it only contained an int*) would be a int**. The const parameter variant would had to be a const int* const*.