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

Accessing the address of an object in a pointer handle

本文关键字:地址 对象 指针 句柄 访问      更新时间:2023-10-16

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

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).

我绝对不知道重载什么运算符,所以如果我在任何表达式中使用"y",它将返回指向对象的地址,就像原始指针所做的一样。我该怎么办?

首先,你的代码有一个错误。构造函数按值获取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
    }
    

你应该重载operator T*() .

请注意,您存储的指针是指向参数的指针,一旦构造函数返回,它就会变得无效,因此在任何位置取消引用它会导致程序未定义。

你可能想要

Ptr(T* t) : p{t} { }

Ptr<int> y = &x;