C ++有一个自初始化指针

时间:2015-03-04 16:16:50

标签: c++ pointers

我有点尴尬地问这么简单的问题:

cpp中是否有任何指针类用nullptr初始化自身,但与基本的c-stylish指针100%兼容?

写:

extern "C" void someFunction(const Struct* i_s);

std::ptr<Struct> p;
// ...
p = new Struct;
// ...
someFunction(p);

有这样的事吗? 或者也许在boost或Qt?

编辑:说清楚:我没有搜索获取指针所有权的智能指针并重新计数。

4 个答案:

答案 0 :(得分:5)

您可以使用以下语法

std::unique_ptr<Struct> up{};

(或std::shared_ptr)。这样,指针就会被初始化,即分配给nullptr

有关默认构造函数的详细信息,请参阅http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr


如果您正在寻找一个默认情况下使用nullptr初始化的“智能”指针,那么您可以编写一个包装器。以下非常基本版本:

#include <iostream>

template <typename T>
struct safe_ptr
{
    T* _ptr;
    explicit safe_ptr(T* ptr = nullptr):_ptr{ptr}{}
    operator T*() const {return _ptr;}
    safe_ptr& operator=(T* rhs)
    {
        _ptr = rhs;
        return *this;
    }
};

void test(int* p){}

int main()
{
    safe_ptr<int> s;
    if(s==nullptr)
        std::cout << "Yes, we are safe!" << std::endl;
    // test that it "decays"
    test(s);

    s = new int[10]; // can assign 
    delete[] s; // can delete
}

答案 1 :(得分:1)

在C ++中没有这样的东西,因为除了“由其他人维护”之外,所有特殊指针类都实现某种形式的所有权。您可以在技术上使用shared_ptr一个空的删除器,但这会添加您实际上不需要的引用计数。

正确的C ++解决方案是始终将= 0;= nullptr;添加到未在声明时初始化的原始指针声明。

所有这一切,这个问题被标记为C ++,所以惯用的答案是不在代码中使用原始指针(显然除了非拥有的情况)。

答案 2 :(得分:1)

  

100%兼容基本的C时尚指针

std::unique_ptrstd::shared_ptr没有自动转换为原始指针,这是一件好事,因为它不可避免地会导致可怕的错误。他们取得所有权,并在您的评论中明确说:

  

指针不应取得给定指针的所有权。

如果你坚持,你可以定义一个&#34; smart&#34;指针类自己:

template <class T>
class RawPointer final
{
private:
    T* raw_ptr;
public:
    RawPointer(T* raw_tr) : raw_ptr(raw_ptr) {}
    RawPointer() : raw_ptr(nullptr) {}
    operator T*() const { return raw_ptr; }
};

struct Struct
{
};

void someFunction(const Struct* i_s);

int main()
{
    RawPointer<Struct> p;
    someFunction(p);
}

这是个好主意吗?可能不是。你应该养成初始化原始指针的习惯:

Struct* p = nullptr;

另一方面,人们正在考虑将来对标准库的一个非常类似的补充。您可能会发现A Proposal for the World’s Dumbest Smart Pointer一个有趣的读物。

答案 3 :(得分:1)

如果这确实是您想要的行为,那么在模板中自己实现它将是微不足道的。这是一个这样的实现:

template<class T>
class ptr_t{
    T* ptr;
public:
    ptr_t() : ptr(nullptr){ }       
    ptr_t(const ptr_t& other) : ptr(other.ptr){ }
    ptr_t(T* other) : ptr(other){ }
    T& operator*(){
        return *ptr;
    }
    T* operator->(){
        return ptr;
    }
    template<class U>
    operator U(){
        return (U)ptr;
    }
}

但是,您从这种设备中获得的便利性将相当有限。采取另一种方法可能会好得多。