访问指针句柄中对象的地址

时间:2014-12-18 11:05:18

标签: c++ pointers c++11

我正在创建一个指针类,但我无法弄清楚如何返回由我的类处理的原始指针的值(指向的对象的地址)。我的班级是这样的。

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;我绝对不知道过载的操作符是什么。在任何表达式中,它将返回指向的对象的地址,就像原始指针一样。我该怎么办?

2 个答案:

答案 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;