Q: why I cannot use "const string* sp = 0" to initialize in a constructor my problem is that const string* p gives me an error. What is wrong with this? since I am not change the original value. const int& n = 0 works fine. 
#include <iostream>
using namespace std;
class HasPtr
{
private:
    int num;
    string* sp;
public:
    //constructor
    HasPtr(const int& n = 0, const string* p = 0): num(n), sp(p) {}
    //copy-constructor
    HasPtr(const HasPtr& m): num(m.num), sp(m.sp) {}
    //assignment operator
    HasPtr& operator=(const HasPtr& m)
    {
        num = m.num;
        sp = m.sp;
        return *this;   
    }
    //destructor
    ~HasPtr() {}
};
int main ()
{
    return 0;
}

output Error is : 
error: invalid conversion from 'const std::string*' to 'std::string*'


A: private:
    int num;
    string* sp;

sp is non-const, but p is:
const string* p = 0

The result is that this sp(p) is basically this:
string* sp = (const string*)0;

It's complaining because doing this would remove the string's const-ness.

A: This is because your sp member is not const.
string* sp;

But your parameter p is a const. The result is that you are trying to assign a const pointer to a non-const pointer - hence the error.
To fix this, you need to declare sp const at as well.
const string* sp;


A: I think you got confused by the various meanings of const.
 const string*sp;

declares a pointer to a constant object, which only allows access to constant methods of class string. 
 string*const sp;

declares a pointer to a string to be a constant member of the class, which you must initialise sp in the constructor and cannot change (except using const_cast<>).
 const int&num;

in the argument list means that the function promises not to alter the value of the integer referred to by num, but it can of course copy its value (as you did). The corresponding operation for the string pointer would have been
 HasPtr(string*const&p) : sp(p) { /* ... */ }

and would have been perfectly legal albeit rather unorthodox.
