问题:我的POD变量结构很大,我需要在某些字段中进行复制,而在其他字段中则不需要。懒得写下每个成员的复制功能。

解决方案:将可复制字段移动到基准,然后分配基准。像这样:

struct A
{
   int a, b, c;
};

struct B : public A
{
    int d, e, f;
};

//And copy:

B x, y;
(A&)x = y; //copies the part of B that is A

现在,这很脏,我知道。我与同事进行了现场生动的讨论,内容涉及:这段代码,我的能力和我的道德品质。但是,我听到的最困难的具体指控是“副本中未初始化d,e,f”。是的我知道;那是目的。当然,我在其他地方初始化它们。

另一个指控是“不安全的类型转换”。但这是对基类的保证安全的类型转换!差不多
((A*)&x)->operator=(b);

但不那么冗长。推导是公开的;因此将B视为A是公平的游戏。据我所知,没有未定义的行为。

因此,我呼吁SO的集体智慧。这是批评的邀请。来吧,人们。

编辑:该代码段的最后一行可以通过一种以上的方式扩展为更具攻击性的代码。例如:
void Copy(A& to, const A& from)
{
    to = from;
}

B x, y;
Copy(x, y);

功能上相同。或像这样:
x.A::operator=(y);

EDIT2:除了我之外,没有维护程序员。这是一个业余项目。因此,不要怜悯那个可怜的灵魂。

最佳答案

这全都取决于上下文以及在这里哪个部分被认为是“肮脏的”。

首先,“ slice 复制”技巧在技术上是合法的。从形式上来说,它并不是真正的“黑客”。您还可以通过使用赋值运算符的限定名称从A引用该运算符来获得相同的结果。

x.A::operator =(y); // same as `(A&) x = y` in your case

它开始看起来很熟悉,不是吗?是的,如果您必须突然决定手动执行此操作,那么必须在派生类中实现赋值运算符时,这就是您要执行的操作
B& B::operator =(const B& rhs)
{
  A::operator =(rhs); // or `this->A::operator =(rhs)`

  // B-specific part goes here
}
A::operator =(rhs);部分与您上面的“ slice 复制”技巧完全相同,但是在这种情况下,它用于不同的上下文中。当然,没有人会责备您使用后者,因为这通常是这样做的,应该这样做。因此,再次,技巧的特定应用的“肮脏性”取决于上下文。作为派生的赋值运算符的实现的组成部分,它非常好,但是如您所使用的那样,当“单独使用”时,它可能看起来很可疑。

但是,第二点,也是更重要的一点,在您的情况下,我所说的“肮脏”不是“ slice 复制”本身的技巧。根据您在问题中描述的内容,看起来您实际上是将数据结构分为两个类(AB),专门用于能够使用上述技巧。在这种情况下,这就是我所说的“肮脏”。不是“ slice 复制”技巧本身,而是将继承用于启用“ slice 复制”的唯一目的。如果这样做只是为了避免手动编写赋值运算符,那就是公然懒惰的一个实例。这就是这里的“肮脏”。我不建议将继承用于这种纯粹的功利目的。

关于c++ - 强制转换为基本引用并复制是一个肮脏的技巧,但是到底是什么肮脏呢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2073341/

10-12 00:45
查看更多