我见过的每个实现五条规则的例子都在没有继承和多态(虚函数)的类上实现规则。
如何将5的规则应用于示例代码?
测试示例使用c-arrays作为动态对象。 当然,为了让动态对象能够管理以演示五级规则,这有点做作。实际上,它可能是任何东西(文件ptrs,数据库句柄等)。因此,不建议使用向量,或将练习转化为零规则的演示。
我更倾向于不使用复制交换习惯用法的解决方案,因为在非继承类的情况下,我发现非复制交换方法更明确。但是,如果有人希望说明这两种方法,那也会很棒。
关于示例代码的说明:
示例代码
//TEST TYPE
class T
{
public:
T() { cout << "ctorT" << endl; }
~T() { cout << "dtorT" < endl; }
T(const T& src) { cout << "copy-ctorT " << endl; }
T& operator=(const T& rhs) { cout << "copy-assignT" << endl; return *this; }
T(T&& src) noexcept { cout << "move-ctorT " << endl; }
T& operator=(T&& rhs) { cout << "move-assignT" << endl; return *this; }
}
class A
{
string nameParent = "A";
size_t bufferSizeParent = 0;
T *pBufferParent = nullptr; //c-array
public:
A(string tNameParent, size_t tBufferSizeParent) : nameParent(tNameParent), bufferSizeParent(tBufferSizeParent)
{
cout << "ctorA " << nameParent << endl;
}
virtual ~A(){ cout << "dtorA " << nameParent << endl; }
virtual string getName() { return nameParent; }
virtual void setName(const string name) { nameParent = name; }
};
class B : public A
{
string nameChild = "B";
size_t bufferSizeChild = 0;
T *pBufferChild = nullptr; //c-array
public:
B(string tNameChild, string tNameParent, size_t tBufferSizeChild, size_t tBufferSizeParent)
: A(tNameParent, tBufferSizeParent), nameChild(tNameChild), bufferSizeChild(tBufferSizeChild)
{
cout << "ctorB " << nameChild << endl;
}
~B(){ cout << "dtorB " << nameChild << endl; }
virtual string getName() override final { return nameChild; }
virtual void setName(const string name) override final { nameChild = name; }
};
答案 0 :(得分:0)
一个好的经验法则是,一个班级应该直接管理最多一个资源。其他类具有所有default
个特殊成员,最好是隐式的,但如果要在某些变体中声明它们,则应明确。
您的示例变为
struct T;
extern T acquire_T();
extern void release_T(T);
class THandle
{
T handle;
public:
THandle()
: handle(acquire_T()) {}
~THandle() { release_T(handle); }
THandle(const THandle &) = delete;
THandle(THandle && other)
: handle(other.handle)
{ other.handle = {}; }
THandle & operator=(const THandle &) = delete;
THandle & operator=(THandle && other)
{ std::swap(handle, other.handle); }
}
class A
{
std::string nameParent = "A";
std::size_t bufferSizeParent = 0;
THandle tParent;
public:
A() {}
A(std::string tNameParent, std::size_t tBufferSizeParent) : nameParent(tNameParent), bufferSizeParent(tBufferSizeParent)
{ }
virtual ~A() = default;
A(const A &) = default;
A(A &&) = default;
A & operator=(const A &) = default;
A & operator=(A &&) = default;
virtual string getName() { return nameParent; }
virtual void setName(const string name) { nameParent = name; }
};
class B : public A
{
std::string nameChild = "B";
std::size_t bufferSizeChild = 0;
THandle tChild;
public:
B() {}
B(string tNameChild, string tNameParent, size_t tBufferSizeChild, size_t tBufferSizeParent)
: A(tNameParent, tBufferSizeParent), nameChild(tNameChild), bufferSizeChild(tBufferSizeChild), bufferChild(std::make_unique(tBufferSizeChild))
{ }
virtual string getName() override final { return nameChild; }
virtual void setName(const string name) override final { nameChild = name; }
};