我正在创建一个指针类,但我无法弄清楚如何返回由我的类处理的原始指针的值(指向的对象的地址)。我的班级是这样的。
template<typename T>
class Ptr {
public:
Ptr(T t) :p{&t} { }
T* operator->() { return p; }
T& operator*() { return *p; }
T& operator[](int i) { return p[i]; }
private:
T* p;
};
如果我愿意的话:
int x = 42;
Ptr<int> y = x;
std::cout << y; //should print the address (y.p).
如果我使用&#34; y&#34;我绝对不知道过载的操作符是什么。在任何表达式中,它将返回指向的对象的地址,就像原始指针一样。我该怎么办?
答案 0 :(得分:4)
首先,您的代码有错误。你的构造函数正在通过值获取t
,这意味着p
将存储将在构造函数出口处死亡的临时t
的地址(并且指针将变得晃来晃去)。你可能想要这个:
Ptr(T &t) : p{&t} {}
即便如此,这意味着您的指针包装器将由对象初始化,而不是由指针初始化,这看起来是违反直觉的。我将构造函数更改为接受T*
。
其次,你问的是如何获得“ >>原始指针的地址”,但我认为你真的希望“地址存储在原始指针中。 “
有了这个,让我们转向你的问题。有几种方法可以解决这个问题。
一个是给你的班级隐式转换为T*
,如下所示:
operator T* () const
{ return p; }
这样,将存在从Ptr<T>
到T*
的隐式转换,并且编译器将在必要时使用它,但这可能比您想要的更多。
更受限制的版本是明确转换:
explicit operator T* () const
{ return p; }
现在你必须明确地转换为指针:
std::cout << static_cast<int*>(y);
您可以按照std
智能指针使用的模式进行操作,并提供get()
功能:
T* get() const
{ return p; }
std::cout << y.get();
最后,如果您只想要此功能进行流媒体播放,则可以为您的课程重载operator<<
:
template <class T, class Char, class Traits>
std::basic_ostream<Char, Traits>& operator<< (std::basic_ostream<Char, Traits> &stream, const Ptr<T> &ptr)
{
return stream << ptr.operator->(); // or ptr.get(), if you implement it
}
答案 1 :(得分:2)
你应该重载operator T*()
。
请注意,您存储的指针是指向参数的指针,并在构造函数返回后立即变为无效,因此在任何地方取消引用都会导致程序未定义。
你可能想要
Ptr(T* t) : p{t} { }
和
Ptr<int> y = &x;