复制构造函数const char*和Shared_ptr
Copy Constructor const char* and Shared_ptr
我有一个类Keywords
:
#include <boost/lambda/lambda.hpp>
class Keywords
{
public:
///Constructor
Keywords(const char*,vector<shared_ptr<RegularExpression>>,vector<string>);
Keywords(const Keywords& other);
private:
const char * xmlFile;
vector<shared_ptr<RegularExpression>> vreg;
vector<string> sw;
}
我想为const char*
和vector<shared_ptr<RegularExpression>>
构建一个副本构造函数
我的编码正确吗?
Keywords::Keywords(const Keywords& other):xmlFile(new char[100]),vreg(other.vreg.size())
{
strcpy((char*)xmlFile, (char*)other.xmlFile);
for (std::size_t i = 0; i < other.vreg.size(); ++i)
vreg[i] = shared_ptr<RegularExpression>(new RegularExpression(*other.vreg[i]));
}
根据我的理解,我复制了Const char*和shared_ptr的向量。
谢谢。
*所以删除const char*后,我将有*
class Keywords
{
public:
///Constructor
Keywords(string,vector<shared_ptr<RegularExpression>>,vector<string>);
Keywords(const Keywords& other);
private:
string xmlFile;
vector<shared_ptr<RegularExpression>> vreg;
vector<string> sw;
}
复制构造函数是:
Keywords::Keywords(const Keywords& other):vreg(other.vreg.size()),sw(other.sw)
{
for (std::size_t i = 0; i < other.vreg.size(); ++i)
vreg[i] = shared_ptr<RegularExpression>(new RegularExpression(*other.vreg[i]));
}
Destcrutor:
Keywords::~Keywords()
{
sw.clear();
vreg.erase(vreg.begin());
}
这里有两个选项。您可能想要使用的是编译器提供的默认副本构造函数:
class Keywords {
std::string xmlFile;
std::vector<std::shared_ptr<RegularExpression>> vreg;
std::vector<std::string> sw;
public:
Keywords(const char *xmlFile,
const std::vector<std::shared_ptr<RegularExpression>>& vreg,
const std::vector<std::string>& sw)
: xmlFile(xmlFile), vreg(vreg), sw(sw) {}
// Look, Ma, no special member functions!
};
在这种情况下,默认的复制构造函数将完全按照您(最有可能)的意愿执行:它将复制vreg
向量,这意味着复制向量的shared_ptr元素,而不是深度复制RegularExpression对象本身!你(很可能)不想深度复制这些对象,因为它们的复制成本很高,我想使用原件和使用副本同样合适。通常情况下,你必须担心内存管理——既然两个不同的Keywords
对象声称拥有原始文件,谁的工作是释放它们?——但在这种情况下,这是100%解决的,因为两个Keywords
对象将共享所有权。这就是shared_ptr
所做的。
这是零规则的一个很好的例子。熟悉的三(或五,或六)规则说,如果你定义了一个特殊的成员函数,你应该定义所有的。零规则说你不应该定义任何特殊的成员函数,除非你在做一些真正的欺骗。
如果希望在这里耍花招,并编写一个自定义复制构造函数,可以对RegularExpression
元素进行深度复制,
好吧,你应该问问自己,为什么一开始就不使用std::vector<RegularExpression> vreg
——然后你仍然可以使用零规则,因为默认的复制构造函数会为你制作深度复制,就像你显然想要的那样。
但如果你想做一些欺骗的事情,你会这样做:
class Keywords {
std::string xmlFile;
std::vector<std::shared_ptr<RegularExpression>> vreg;
std::vector<std::string> sw;
public:
Keywords(const char *xmlFile,
const std::vector<std::shared_ptr<RegularExpression>>& vreg,
const std::vector<std::string>& sw)
: xmlFile(xmlFile), vreg(vreg), sw(sw) {}
Keywords(const Keywords& rhs)
: xmlFile(rhs.xmlFile), sw(rhs.sw)
{
vreg.reserve(rhs.vreg.size());
for (auto&& sptr : rhs.vreg) {
vreg.emplace_back(std::make_shared<RegularExpression>(*sptr));
}
}
// Don't forget to implement copy-assignment too!
// I'm just going to delete it here to keep anyone from using it.
//
Keywords& operator= (const Keywords&) = delete;
};
此实现可能仍然不能执行您想要的操作;例如,如果在复制操作之前,我们有rhs.vreg[0] == rhs.vreg[1]
,那么我们的构造函数将悄悄地对单个RegularExpression
对象进行两次复制,并给我们一个新的Keywords
对象*this
,使this->vreg[0] != this->vreg[1]
。这只是一般原理的一个具体应用,即很难复制任意指针图。
你注意到这行代码有多长了吗?
vreg.emplace_back(std::make_shared<RegularExpression>(*sptr));
这是普通C++11中的一个危险信号。在普通代码中,我们不必编写像RegularExpression
这样的显式类型;编译器只能推断类型。如果我想复制sptr
,我可以只写vreg.emplace_back(sptr)
——没有显式类型!但在这里我不得不写出std::make_shared<RegularExpression>(...)
。这很尴尬因为我做错了取一个shared_ptr
,取消对它的引用,复制构造shared_ptr
指向的,然后将其重新封装在具有不同所有权的新shared_ptr
中,这不是正常的。这是一个复杂而奇怪的操作,因此在C++11中执行此操作的语法复杂而奇怪是有道理的。
在这种情况下,我建议不要耍花招。:)
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理