gpt4 book ai didi

c++ - 在具有继承的模板中复制构造函数和赋值运算符

转载 作者:行者123 更新时间:2023-12-05 04:33:14 24 4
gpt4 key购买 nike

template<typename T = uint8_t> class ArrayRef {
using uint = unsigned int;
protected:
ArrayRef() {}
ArrayRef(const ArrayRef&) {}
ArrayRef& operator=(const ArrayRef& other) { return *this; }
};

class ByteArray : ArrayRef<uint8_t> {
ByteArray(const ArrayRef&);
ByteArray& operator=(const ArrayRef&);
public:
ByteArray() {}
};

class Base {
using uint = unsigned int;
protected:
Base() {}
Base(const Base&) {}
Base& operator=(const Base& other) { return *this; }
};

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

int main() {
ByteArray ba;
ByteArray ba2 = ba; // no error, why?
ba = ba2; // no error why?
Derived d;
Derived d2 = d; // error (expected) - Calling a private constructor
d = d2; // error (expected) - Calling private assignment operator
}

关于上面代码的两个问题。

  • 您能解释一下为什么模板化代码的行为与非模板化代码不同吗? (参见 main() 中的注释。
  • 我将如何为这样的模板代码正确创建私有(private)复制构造函数和赋值运算符,以防止对象复制?

最佳答案

  • Can you explain why the templated code behaves differently than the non-templated code? (see the comments in main().

区别与模板任何无关。

区别在于您的复制构造函数和复制赋值运算符是在 public 中隐式定义的(如 ByteArray ) .在 Derived你做到了 private .如果您将模板排除在外,可能更容易看出两个版本之间的区别:

class ArrayRef {
protected:
ArrayRef() {}
ArrayRef(const ArrayRef&) {}
ArrayRef& operator=(const ArrayRef& other) { return *this; }
};

class ByteArray : ArrayRef {
ByteArray(const ArrayRef&); // your converting ctor
ByteArray& operator=(const ArrayRef&); // your converting assignment op
public:
ByteArray() {}

// copy contructor - implicitly defined:
// ByteArray(const ByteArray&) = default;

// copy assignment operator - implicitly defined:
// ByteArray& operator=(const ByteArray&) = default;
};

如果您现在尝试复制 ByteArray它会像基于类模板实例时一样正常工作。比较以上ByteArray用你的Derived您实际上在其中创建了复制构造函数和复制赋值运算符 private .

  • How would I go about creating private copy constructors and assignment operators properly for templated code like this, in order to prevent object copies?

为了防止复制,您可以delete他们:

class ByteArray : private ArrayRef<uint8_t> {
public:
ByteArray(const ByteArray&) = delete;
ByteArray& operator=(const ByteArray&) = delete;
ByteArray() {}
};

或制作它们 private允许 ByteArray s 和 friend s 制作拷贝:

class ByteArray : private ArrayRef<uint8_t> {
private:
ByteArray(const ByteArray&) { ... }; // or `= default`
ByteArray& operator=(const ByteArray&) { ...; return *this; } // or `= default`
public:
ByteArray() {}
};

请注意 private采用 const ArrayRef<uint8_t>& 的(转换)构造函数和(转换)赋值运算符因为输入不会阻止隐式定义的 copy 构造函数和 copy 赋值运算符,它采用 const ByteArray&作为在 ByteArray 中创建的 behing 的输入.

在你的Derived类,你实际上已经创建了复制构造函数和复制赋值运算符 private这就是为什么在尝试使用它们时会出现预期的编译错误。

这是一个完整的示例,其中包括您的(转换)构造函数和赋值运算符以及(用户定义的)复制构造函数和复制赋值运算符。

#include <cstdint>
#include <iostream>

template<typename T = uint8_t> class ArrayRef {
protected:
ArrayRef() {}
ArrayRef(const ArrayRef&) {}
ArrayRef& operator=(const ArrayRef& other) { return *this; }
};

class ByteArray : ArrayRef<uint8_t> {
ByteArray(const ArrayRef&) { std::cout << "your converting ctor\n"; }
ByteArray& operator=(const ArrayRef&) {
std::cout << "your converting assignment op\n"; return *this;
}

public:
ByteArray(const ByteArray&) { std::cout << "copy ctor\n"; }
ByteArray& operator=(const ByteArray&) {
std::cout << "copy assignment op\n"; return *this;
}
ByteArray() {}
};

int main() {
ByteArray a;
ByteArray b = a;
a = b;
}

您可以在输出中看到您的 private 都没有使用方法:

copy ctor
copy assignment op

关于c++ - 在具有继承的模板中复制构造函数和赋值运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71474828/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com