0

我需要我的Base类的静态方法来获得 type 的默认参数值Derived。有没有办法在不使用重载的情况下实现这一点?(见这里)。

class Base;
class Derived;
Derived make_derived(void);

class Base
{
  public:
    static void problem_here(Base && = make_derived());
};

class Derived : public Base
{
};

Derived make_derived()
{
  return Derived();
}

...给我一个关于不完整类型的使用的错误Derived。但是,我不能将 的定义Derived放在前面,problem_here因为它必须在其基类的定义之后定义Base

不幸的是,返回指针 frommake_derived不是一种选择。

重载problem_here是我到现在为止唯一想到的东西,但是由于“真实”problem_here方法需要 2 个(另外一个是 3 个)参数,并且它是库的一部分,这给了我......

static void problem_here(Thing const &, Base const &);
static void problem_here(Thing const &, Base &&);
static void problem_here(Thing const &); // Default param "hack"
static void problem_here(Thing &&, Base const &);
static void problem_here(Thing &&, Base &&);
static void problem_here(Thing &&); // Default param "hack"

..仅适用于两个参数情况。

有没有办法避免编写所有这些函数签名,同时仍然保持相同的性能(没有任何参数星座的不必要的复制/移动构造)和调用者站点上的相同行为?


我应该补充一点,有多个函数problem_here都需要访问受保护的构造函数Derived(以及它的许多兄弟姐妹的构造函数)。因此,使这些方法成为 Base 的静态成员的主要原因是能够friend class Base;在每个派生类中,而不是与每个函数交朋友。


重构告诉我,我可以将访问派生类的受保护构造函数的代码移动到单个工厂函数中。这样,我就可以将带有默认参数的函数移到外面Base并让工厂调用。现在我仍然需要为这些功能中的每一个加好友,但只需要一次(Base让他们访问工厂)。我可以通过将所有函数放入一个辅助类并使其成为朋友来规避这一点,但这对我来说似乎是一种黑客行为。

class Base
{
  friend class Helper; // The Hack
  friend void no_problem_here(Base &&); // No hack, more writting


  protected:
    static void factory(Thing && from_which_I_can_construct_the_correct_derived_class);
    // return type void to keep it simple, move parameter type because special cases
    // handled in "trampoline" functions and a copy of the Thing must be stored either
    // way.
};
class Derived : public Base
{
  friend class Base;
  // protected constructor omited for simplicity.
}


void no_problem_here(Base && = make_derived());
// ...
void no_problem_here(Base && b)
{
   // work, and then call Base::factory
}

// or

class Helper
{
  protected:
    // Constructors ...
  public:
    static void no_problem_either(Base && = make_derived());
};
4

1 回答 1

4

您可以多次声明,因此以下解决方法可能会有所帮助:

class Base;
class Derived;
Derived make_derived(void);

class Base
{
public:
    static void problem_here(Base &&);
};

class Derived : public Base {};

void Base::problem_here(Base && = make_derived()) { /* ... */ }

如果在分解这样的代码时出现问题,您可以随时插入一个小蹦床函数:

 class Base
 {
 public:
     static void problem_here(Base &&);
 private:
     static void problem_here_impl(Base &&);
 };

 inline void Base::problem_here(Base && x = make_derived())
 { problem_here_impl(std::move(x)); }
于 2014-03-07T09:47:42.670 回答