我正在试验智能指针,并编写了以下代码:
struct Buffer
{
char Data[128];
};
class SmartPtr {
char * dataPtr;
public:
SmartPtr(Buffer& b)
{
dataPtr = b.Data;
}
~SmartPtr()
{
cout << "desctructor called" << endl;
}
void operator=(Buffer & b)
{
dataPtr = b.Data;
}
char*& operator*()
{
return dataPtr;
}
};
我认为,当使用与类的第一个成员类型相同的指针时,我可以访问该成员
我试图通过获取对象p
的地址来访问dataPtr
我希望p
和dataPtr
具有相同的地址。
以下代码打印垃圾。
static Buffer buff;
int main(void)
{
strcpy(buff.Data, "Hello world");
SmartPtr p = buff;
char* s = (char*)&p;
cout << "Data: " << s << endl;
return 0;
}
输出:
Data: Ç☺┴─≈
desctructor called
如果我把它改为双指针,我会得到预期的结果
static Buffer buff;
int main(void)
{
strcpy(buff.Data, "Hello world");
SmartPtr p = buff;
char** s = (char**)&p;
cout << "Data: " << *s << endl;
return 0;
}
输出:
Data: Hello world
desctructor called
这是因为使用单个指针时,我将实际指针的地址作为变量而不是它所包含的地址来取消引用吗?
在第一个代码中,获取p
的地址(因此也是p.dataPtr
的地址(,将其强制转换为char*
,然后按原样打印。因此,operator<<
误解了p
本身的原始内存,就好像它是一个以null结尾的字符串,而事实并非如此,所以你会得到垃圾。
在第二个代码中,您将获取p
的地址(以及p.dataPtr
的地址(,将其强制转换为char**
,取消引用以访问其值作为char*
,然后打印该值。因此,operator<<
将p.dataPtr
所指向的数据打印为一个以null结尾的字符串,因此您可以得到正确的结果。