use*_*536 42 c++ const shared-ptr
我在类中有一些容器,例如vector或map,它包含生活在堆上的对象的shared_ptr.
例如
template <typename T>
class MyExample
{
public:
private:
vector<shared_ptr<T> > vec_;
map<shared_ptr<T>, int> map_;
};
Run Code Online (Sandbox Code Playgroud)
我希望有一个这个类的公共接口,有时会将shared_ptrs返回给const对象(via shared_ptr<const T>),有时shared_ptr<T>我允许调用者改变对象.我想要逻辑const正确性,所以如果我将方法标记为const,它就不能更改堆上的对象.
问题:
1)我对shared_ptr<const T>和的可互换性感到困惑shared_ptr<T>.当有人经过一个shared_ptr<const T>shared_ptr的进级,做我把它存储为一个shared_ptr<T>或shared_ptr<const T>载体内,映射或修改我的地图,矢量类型(例如insert_elemeent(shared_ptr<const T>OBJ)?
2)如下实例化类更好MyExample<const int> 吗?这看起来过于严格,因为我永远无法回归shared_ptr<int>?
Ter*_*fey 37
shared_ptr<T>和shared_ptr<const T>是不是可以互换的.这是一种方式 - shared_ptr<T>可转换为shared_ptr<const T>但不是相反的.
注意:
// f.cpp
#include <memory>
int main()
{
using namespace std;
shared_ptr<int> pint(new int(4)); // normal shared_ptr
shared_ptr<const int> pcint = pint; // shared_ptr<const T> from shared_ptr<T>
shared_ptr<int> pint2 = pcint; // error! comment out to compile
}
Run Code Online (Sandbox Code Playgroud)
编译通过
cl/EHsc f.cpp
您还可以基于常量重载函数.你可以结合起来做这两件事来做你想做的事.
至于你的第二个问题,MyExample<int>可能更有意义MyExample<const int>.
mmm*_*mmm 12
我建议以下的methotology:
template <typename T>
class MyExample
{
private:
vector<shared_ptr<T> > data;
public:
shared_ptr<const T> get(int idx) const
{
return data[idx];
}
shared_ptr<T> get(int idx)
{
return data[idx];
}
void add(shared_ptr<T> value)
{
data.push_back(value);
}
};
Run Code Online (Sandbox Code Playgroud)
这确保了正确性.就像你看到add()方法不使用<const T>而是<T>,因为你打算让类存储Ts而不是const Ts.但是当访问它时,返回<const T>这是没有问题的,因为shared_ptr <T>可以很容易地转换为shared_ptr <const T>.并且两个get()方法都会在内部存储中返回shared_ptr的副本,调用者不会意外地更改内部指针指向的对象.这与非智能指针变体完全相同:
template <typename T>
class MyExamplePtr
{
private:
vector<T *> data;
public:
const T *get(int idx) const
{
return data[idx];
}
T *get(int idx)
{
return data[idx];
}
void add(T *value)
{
data.push_back(value);
}
};
Run Code Online (Sandbox Code Playgroud)
如果有人通过你,shared_ptr<const T>你就永远无法修改T.当然,技术上可以将其转换const T为a T,但这打破了制作它的意图T const.因此,如果您希望人们能够向您的班级添加对象,他们应该给您shared_ptr<T>而不是shared_ptr<const T>.当你从班级中归还你不需要修改的东西时,那就是你使用的时候shared_ptr<const T>.
shared_ptr<T>可以自动转换(没有显式转换)到一个shared_ptr<const T>但不是相反的方式.它可以帮助你(无论如何你应该这样做)自由地使用const方法.定义类方法时const,编译器不允许您修改任何数据成员或返回除a之外的任何内容const T.因此,使用这些方法可以帮助您确保不会忘记某些内容,并且可以帮助您的班级用户了解该方法的用途.(实施例:virtual shared_ptr<const T> myGetSharedPtr(int index) const;)
你的第二个陈述是正确的,你可能不想将你的类实例化<const T>,因为你永远无法修改你T的任何一个.
需要认识到的一件事是:
tr1::shared_ptr<const T>T const *正在模仿它所指向的内容是 const 的功能,但指针本身不是。
因此,您可以为共享指针分配一个新值,但我希望您无法将取消引用的值用作shared_ptr左值。