C ++:关于使用Stroustrup示例在工会中新放置的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++:关于使用Stroustrup示例在工会中新放置的问题相关的知识,希望对你有一定的参考价值。
我正在使用来自Stroustrup C ++ 4th Ed的以下示例。 Page 218.我的问题是关于析构函数。
问题:当我了解并集大小固定为最大成员时,位置new(&s) string{ss}
如何为新字符串分配空间? string s
不是0元素字符串吗?如果是这样,如果联合中没有足够的空间,那么placement new将如何创建一个更大的字符串?
#include <iostream>
#include <string>
using namespace std;
class Entry2 { // two alternative representations represented as a union
private:
enum class Tag { number, text };
Tag type; // discriminant
union { // representation
int i;
string s; // string has default constructor, copy operations, and destructor
};
public:
struct Bad_entry { }; // used for exceptions
string name;
Entry2(int n) : type{Tag::number}, i{n} { };
Entry2(string ss) : type{Tag::number} { new(&s) string{ss}; };
~Entry2();
Entry2& operator=(const Entry2&); Entry2(const Entry2&);
// ...
int number() const; string text() const;
void set_number(int n);
void set_text(const string&); // ...
};
Entry2::~Entry2()
{
if (type==Tag::text)
s.~string();
}
int Entry2::number() const
{
if (type!=Tag::number) throw Bad_entry{};
return i;
}
string Entry2::text() const
{
if (type!=Tag::text) throw Bad_entry{};
return s;
}
void Entry2::set_number(int n)
{
if (type==Tag::text) {
s.~string();
type = Tag::number;
}
i = n;
}
void Entry2::set_text(const string& ss)
{
if (type==Tag::text)
s = ss;
else {
new(&s) string{ss};
type = Tag::text;
}
}
Entry2& Entry2::operator=(const Entry2& e)
{
if (type==Tag::text && e.type==Tag::text) {
s = e.s; // usual string assignment
return *this;
}
if (type==Tag::text)
s.~string(); // explicit destroy (§11.2.4)
switch (e.type) {
case Tag::number:
i = e.i;
break;
case Tag::text:
new(&s) string{e.s};
type = e.type;
}
return *this;
}
int main(int argc, char *argv[])
{
Entry2 e0(0);
cout << e0.number() << endl;
try {
e0.text();
} catch (...) {
cout << "caught except" << endl;
}
e0.set_text("abcd");
cout << e0.text() << endl;
return 0;
}
答案
不,析构函数不应该总是这样做。请记住,在union
中,任一时间实际上只有一个字段处于活动状态。如果std::string
的union
成员未处于活动状态,则调用其析构函数将是一件不好的事情(导致未定义的行为),因为那里没有要销毁的字符串。相反,我们仅在先前某个时间点在此std::string
成员上激活了析构函数的情况下才调用该析构函数。
希望这会有所帮助!
以上是关于C ++:关于使用Stroustrup示例在工会中新放置的问题的主要内容,如果未能解决你的问题,请参考以下文章