声明拥有现有原始指针的正确方法

时间:2015-07-08 00:36:43

标签: c++ pointers c++11 const unique-ptr

我有一些代码声称拥有一系列原始指针的所有权,并且我想知道是否有可接受的方法来执行此操作?我正在寻找的是一种在更大程度上强制执行代码所有权的方法。主要是,我一直在想我的构造函数是否应该直接使用一个独特的指针向量。

作为旁注,一旦声称所有权,数据应该是不可变的。

该代码大致遵循以下class X的模式。

#include <iostream>
#include <memory>
#include <vector>
using namespace std; // For readability purposes only

class X {
public:
    const vector< unique_ptr<const int> > data; // In my case this is private

    // Constructor: X object will take ownership of the data 
    // destroying it when going out of scope
    X (vector<int*> rawData) 
        : data { make_move_iterator(rawData.begin()), make_move_iterator(rawData.end()) }
    { }
};


int main() {
    // Illustrating some issues with claiming ownership of existing pointers:
    vector<int*> rawData { new int(9) , new int(4) };
    int* rawPointer = rawData[0];
    { // New scope
        X x(rawData);
        cout << *(x.data[0]) << endl; // Unique pointer points to 9
        *rawPointer = 7;
        cout << *(x.data[0]) << endl; // Unique pointer points to 7
    }
    cout << *rawPointer << endl; // The pointer has been deleted, prints garbage
    return 0;
}

2 个答案:

答案 0 :(得分:4)

如果没有详细了解您的情况,很难发布答案。但我建议您尽快将数据附加到unique_ptr。然后,您可以随意将unique_ptr移入和移出vector。例如:

#include <iostream>
#include <memory>
#include <vector>
using namespace std; // For readability purposes only

class X {
public:
    const vector< unique_ptr<const int> > data; // In my case this is private

    // Constructor: X object will take ownership of the data 
    // destroying it when going out of scope
    X (vector<unique_ptr<const int>>&& v) 
        : data { std::move(v) }
    { }
};

vector<unique_ptr<const int>>
collectRawData()
{
    auto rawData = {9, 4};
    vector<unique_ptr<const int>> data;
    for (auto const& x : rawData)
        data.push_back(make_unique<int>(x));
    return data;
}

int main() {
    auto rawData = collectRawData();
    { // New scope
        X x(std::move(rawData));
        cout << *(x.data[0]) << endl; // Unique pointer points to 9
        cout << *(x.data[1]) << endl; // Unique pointer points to 4
    }
}

答案 1 :(得分:0)

你做了几次错误。

  1. 如果是const vector< unique_ptr<const int> >数据;移动迭代器确实没有多大意义。原因是,int*没有移动构造函数。

  2. 如果您使用X调用X (vector<int*> rawData)的构造函数vector < int* >,则会调用vector < int* >的复制构造函数,但这不是您想要的。 顺便说一句。使用move的原因是,避免大内存拷贝。例如std::vector < int* >:成员属性大小和指向int*存储std::vector<int*>的内存位置的指针必须通过移动复制,但不能复制int*s自。结论是,此举是要求所有权。

  3. 如果您想要这样的共享指针,请使用std::shared_ptr。它拥有一个计数器,计算指向自己的ptrs。

  4. “ 我的示例代码:

    class X
    {
    public:
        const std::vector< std::shared_ptr< const int> > data; // In my case this is private
    
        // Constructor: X object will take ownership of the data 
        // destroying it when going out of scope
        X (std::vector<std::shared_ptr<int>>& rawData) 
            //: data(rawData)
            : data(rawData.cbegin(), rawData.cend())
        { }
    };
    
    
    int main() {
        // Illustrating some issues with claiming ownership of existing pointers:
        std::vector<std::shared_ptr<int>> rawData { std::make_shared<int>(9), std::make_shared<int>(4) };
        int* rawPointer = rawData[0].get();
        { // New scope
            X x(rawData);
            cout << *(x.data[0]) << endl; // Unique pointer points to 9
            *rawPointer = 7;
            cout << *(x.data[0]) << endl; // Unique pointer points to 7
        }
        cout << *rawPointer << endl; // The pointer has been deleted, prints not more garbage
        return 0;
    }
    

    如果您不想使用std::shared_ptr,则需要使用GC。