0

我有一个带有默认构造函数的基类。

class Base
{
public:
   Base();
private:
   Type1 m_ofType1;
   Type2 m_ofType2;
}

Base::Base()
   : m_ofType1(defaultExpr1)
   , m_ofType2(defaultExpr2)
{
}

我有一个派生类,可能是:

  • 默认构造,m_ofType1 和 m_ofType2 由它们各自的默认表达式初始化,
  • 仅提供 Type1,或
  • 仅提供 Type2。
class Derived : public base
{
public:
   Derived(); // m_ofType1 and m_ofType2 will be initialized with their default expressions.

   Derived(Type1 overrideOfType1); // m_ofType1 will be initialized with overrideOfType1 and m_ofType2 will be initialized with its default expression.

   Derived(Type2 overrideOfType2); // m_ofType1 will be initialized with its default expression and m_ofType2 will be initialized with overrideOfType2.
}

Base 用于生产代码,Derived 用于测试代码。我想实现没有数据或代码重复的构造函数,但我不知道如何。

鉴于约束,我希望已经说清楚了,你们都知道如何在没有数据或代码重复的情况下实现上述构造函数吗?

代码重复示例:

我们可以将受保护的构造函数添加到基础:

Base(Type1);
Base(Type2);

这意味着 Derived 构造函数只会将调用转发给它们各自的 Base 构造函数。

Derrived::Derrived()
   : Base()
{
}

Derived::Derived(Type1 overrideOfType1)
   : Base(overrideOfType1)
{
}

Derived::Derived(Type1 overrideOfType2)
   : Base(overrideOfType2)
{
}

在这样做时,问题发生了一些变化。如何在没有数据或代码重复的情况下实现 Base 构造函数。

这是我最好的尝试。它不起作用,我会告诉你为什么。

首先,向 Base 添加另一个构造函数:

Base(Type1 ofType1, Type2 ofType2);

Base::Base() : Base(defaultExpr1, defaultExpr2) { }

Base::Base(Type1 overrideOfType1) : Base(overrideOfType1, defaultExpr2) { }

Base::Base(Type2 overrideOfType2) : Base(defaultExpr1, overrideOfType2) { }

Base::Base(Type1 ofType1, Type1 ofType2) : m_ofType1(ofType1) , m_ofType2(ofType2) { }


You can see that defaultExpr1 and defaultExpr2 have been duplicated.
4

2 回答 2

2

我认为这Derived几乎是一个红鲱鱼。基本上,您要求 3 种方法来构造 aBase并做到这一点,它Base必须提供适当的构造函数,类似于:

struct Base {
   Type1 m_ofType1{defaultExpr1};
   Type2 m_ofType2{defaultExpr2};
   Base() = default;
   Base(Type1 x) : m_ofType1(x) {}
   Base(Type2 x) : m_ofType2(x) {}
};

默认初始值设定项 (defaultExpr1defaultExpr2) 可以被构造函数初始值设定项列表中的初始值设定项覆盖。

现在根据需要添加访问限制和调用这些构造函数的派生类(也许将最后两个受保护的和数据成员设为私有)。继续你的例子,那将是

 struct Derived : Base {
    Derived(Type1 x) : Base(x) {}
    Derived(Type2 x) : Base(x) {}
 };

我怀疑你能得到比这更短的时间。

于 2019-11-20T20:18:51.893 回答
0

您可以使用受保护的构造函数将参数传递给私有成员 1 和 2。这将使这些成员保持屏蔽状态,而不赋予派生类对它们的完全访问权限。

class Base
{
private:
   Base();
protected:
   Base(Type1 overrideOfType1, Type2 overrideOfType2) { }
private:
   Type1 m_ofType1;
   Type2 m_ofType2;
};

class Derived : public Base
{
public:
   Derived() : Base(Type1{}, Type2{}) { }

   Derived(Type1 overrideOfType1) : Base(overrideOfType1, Type2{}) { }

   Derived(Type2 overrideOfType2) : Base(Type1{}, overrideOfType2) { }
};

哦,顺便说一句,如果成员自动具有默认构造函数,则使用默认构造函数进行初始化,因此您不需要为空的基本构造函数显式。例如,如果默认构造函数Base是可访问的,您可以定义:

Base::Base() = default;

并且成员将具有其默认值。

于 2019-11-20T20:12:43.833 回答