简体   繁体   English

在派生类中使用基类Copy CTOR

[英]Use base class Copy CTOR in derived class

I know there are many posts on the subject, but I couldn't find any to fully answer my questions. 我知道这个主题有很多帖子,但我找不到任何完全回答我的问题。

Say I have a Base class and a Derived class, which I implemented a CCtor and an assignment operator for it, something like the following: 假设我有一个Base类和一个Derived类,我为它实现了CCtor和赋值运算符,如下所示:

class Base {
    char * name;
    ....
    Base(const Base& other) :name(nullptr) { *this = other }
    void operator=(const Base& other) { ... Deep copy of name } 
}


class Derived : public Base {
.... 
    Derived(const Derived& other) { *this = other ; }
    void operator=(const Derived& other) {
        Base::operator=(other);
        .....
    }

Now I have some questions about this design. 现在我对这个设计有一些疑问。

  1. Is this the right design for the situation? 这是适合这种情况的合适设计吗?
  2. If i have a third class, between the base and the derived class, but it only contains primitive types, where shoud I copy them ? 如果我有一个第三类,在基类和派生类之间,但它只包含原始类型,我在哪里复制它们? EG use the default assignment operator of the second class ? EG使用第二类的默认赋值运算符? build a new one? 建立一个新的? only copy them on the third level ? 只在第三级复制它们?
  3. I could similary call the base class CCtor inside the derived class CCtor, instead of the assignment operator. 我可以类似地在派生类CCtor中调用基类CCtor,而不是赋值运算符。 What's the difference? 有什么不同? If I place them in both methods will it try to copy the values two times? 如果我将它们放在两种方法中,它会尝试将值复制两次吗?

Edit: Just to clarify, the design is what I was given in my project .. I have pointers so I have to use a deep copy . 编辑:只是为了澄清,设计是我在项目中给出的。我有指针所以我必须使用深层复制。

Is this the right design for the situation? 这是适合这种情况的合适设计吗?

No, not usually. 不,通常不会。 The more idiomatic approach is to stop manually managing memory like char* name and use std::string or another type that does the right thing: 更惯用的方法是停止手动管理内存,如char* name并使用std::string或其他类型做正确的事情:

Class Base {
    std::string name;
    ....
    Base(const Base& other) = default;
    Base& operator=(const Base& other) = default;
};

(Note that assignment operators should return a reference to the class, not void ). (请注意,赋值运算符应该返回对类的引用,而不是void )。

Or encapsulate the memory management in a class design specifically for that purpose (but std::string already is that type). 或者将内存管理封装在专门为此目的的类设计中(但std::string已经是那种类型)。

If you really really need to do it the dumb error-prone way, then implement your copy constructor to do copying: 如果你真的真的需要做哑容易出错,然后实现你的拷贝构造函数做复印:

    Base(const Base& other) { / * deep copy of name */ }

Then implement assignment as copy-and-swap: 然后将赋值实现为copy-and-swap:

    Base& operator=(const Base& other)
    {
      Base tmp(other);
      this->swap(tmp);
      return *this;
    }

This means you need a cheap, non-throwing swap(Base&) member function. 这意味着您需要一个廉价的,非投掷swap(Base&)成员函数。

In any case the derived type copy constructor is just silly. 在任何情况下,派生类型的复制构造函数都是愚蠢的。 You have a correct copy constructor for the base class so it should be: 你有一个正确的基类复制构造函数,所以它应该是:

Derived(const Derived& other) : Base(other) { }

And the assignment can use the base assignment: 赋值可以使用基本赋值:

Derived& operator=(const Derived& other)
{
   Base::operator=(other);
   return *this;
}

But writing these manually is unnecessary, you can just default its copy operations which will Do The Right Thing anyway: 但是手动编写这些是不必要的,你可以默认它的复制操作,无论如何都会做正确的事情:

class Derived : public Base {
public:
    Derived(const Derived&) = default;
    Derived& operator=(const Derived& ) = default;

If i have a third class, between the base and the derived class, but it only contains primitive types, where shoud I copy them ? 如果我有一个第三类,在基类和派生类之间,但它只包含原始类型,我在哪里复制它们? EG use the default assignment operator of the second class ? EG使用第二类的默认赋值运算符? build a new one? 建立一个新的? only copy them on the third level ? 只在第三级复制它们?

You should define the copy constructor and assignment operator of that class using = default as well. 您应该使用= default定义该类的复制构造函数和赋值运算符。 Once you've made Base safe to copy with correct behaviour, composing other classes to use it is trivial. 一旦你使Base安全地以正确的行为进行复制,组成其他类来使用它是微不足道的。 The default behaviour will Do The Right Thing. 默认行为将是正确的事情。 You only need to define those operations manually if you need special treatment for something like dynamically-allocated memory that isn't being correctly managed by an RAII type. 如果您需要对RAII类型未正确管理的动态分配内存等特殊处理,则只需手动定义这些操作。

I could similary call the base class CCtor inside the derived class CCtor, instead of the assignment operator. 我可以类似地在派生类CCtor中调用基类CCtor,而不是赋值运算符。 What's the difference? 有什么不同?

If you want to copy construct then use the copy constructor, not assignment. 如果要复制构造,则使用复制构造函数,而不是赋值。 Use the right function for the job. 使用正确的功能来完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM