好吧,我觉得很慷慨,我自己也成立了海关联盟,所以他是一些可以帮助你建立起来的东西。我已经改写了你的
S
结构更加兼容和可用。(我做了一些修改,并用注释标记)
struct S
{
S() : tag(CC) // initializer
{
new (&c) C; // make C object
}
S(int num) : tag(CC) // added integer constructor
{
new (&c) C;
c.num = num;
}
S(const std::string& str) : tag(BB) // added string constructor
{
new (&b) B;
b.str = str;
}
S( const S& s ) : tag(s.tag)
{
if (tag == CC)
{
new (&c) C; // construct c
c.num = s.c.num;
}
else if (tag == BB)
{
new (&b) B; // construct b, not b.str
b.str = s.b.str;
}
}
S& operator= (const S& s) // added assignment operator
{
if (tag == s.tag) // just copy b or c
{
if (tag == CC)
c = s.c;
else
b = s.b;
}
else // reconstruct b or c
{
if (tag == CC)
{
c.~C(); // destroy c
new (&b) B; // construct b
b.str = s.b.str;
}
else
{
b.~B(); // destroy b
new (&c) C; // construct c
c.num = s.c.num;
}
tag = s.tag;
}
return *this;
}
~S()
{
if (tag == CC)
{
c.~C(); // destroy c
}
else if (tag == BB)
{
b.~B(); // destroy b, not b.str
}
}
enum { BB, CC } tag;
union
{
B b;
C c;
};
};
你做得不正确的一件事是跳过
B
和
C
直接计算内部变量。您应该始终正确地创建和销毁类型,即使它们可能微不足道。虽然这可能可行,但不正确初始化这些对象只会带来麻烦(如果更改也会更容易
B
或
C
未来)。
为了简化类的使用,我为添加了适当的构造函数
std::string
和
int
以及赋值运算符。因为现在我们可以按照我们想要的方式构造对象
main()
可能如下所示:
int main()
{
S s; // default S
s = std::string("bbb"); // set to string
s = 333; // set to number
// use initialization list
H h { std::string("bb"), 33, std::string("bb") };
return 0;
}
我鼓励你修改
B
和
C
使用构造函数来构建其内部构件,而不是依赖于
S
.