我有两个 C++ 类,SuperClass 和 SubClass。它们每个都有一个 set 函数,该函数将在最后返回类对象本身,因为我想在一行中执行它们。代码如下所示:
class SuperClass
{
public:
SuperClass& SetA(int a)
{
m_a = a;
return *this;
}
virtual void Print()
{
printf("a=%i", m_a);
}
protected:
int m_a;
};
class SubClass : public SuperClass
{
public:
SubClass& SetB(double b)
{
m_b = b;
return *this;
}
virtual void Print()
{
printf("a=%i, b=%f", m_a, m_b);
}
protected:
double m_b;
};
int main(int argc, char* argv[])
{
SubClass().SetB(123.4).SetA(123).Print(); // Works fine
SubClass().SetA(123).SetB(123.4).Print(); // Failed
}
但是,SetA() 函数返回父类(super class)的定义,所以我不能将它与子类中声明的 SetB() 函数链接起来。
有没有办法让 SetA() 函数返回子类的定义?这样我就可以在一行中执行它们。
提前致谢。 埃利奥特
CRTP 方法的问题更新(2014 年 9 月 24 日): 感谢所有评论。我认为 CRTP 是解决这个问题的好方法。但是,我也想单独使用 SuperClass。说:
int main(int argc, char* argv[])
{
SubClass().SetB(123.4).SetA(123).Print(); // Works fine
SubClass().SetA(123).SetB(123.4).Print(); // Failed, but works in CRTP
SuperClass().SetA(123).Print(); // Is CRTP able to do this?
}
在这种情况下,CRTP 方法是否也有帮助?
再次感谢。 埃利奥特
最佳答案
It seems CRTP is a good way to solve this. However, may I use the SuperClass alone under this approach?
#include <type_traits>
// make it a template
template <typename T = void>
class SuperClassCRTP
{
// determine what type SetA (and others) should return
using CRTP = typename std::conditional<std::is_same<T, void>::value
, SuperClassCRTP
, T>::type;
public:
// return CRTP& instead:
CRTP& SetA(int a)
{
m_a = a;
return static_cast<CRTP&>(*this); // cast the *this to desired type
}
virtual void Print()
{
printf("a=%i", m_a);
}
protected:
int m_a;
};
class SubClass : public SuperClassCRTP<SubClass>
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
// specialize the base class with self type
{
public:
SubClass& SetB(double b)
{
m_b = b;
return *this;
}
virtual void Print()
{
printf("a=%i, b=%f", m_a, m_b);
}
protected:
double m_b;
};
// define an alias
using SuperClass = SuperClassCRTP<>;
int main()
{
SubClass().SetB(123.4).SetA(123).Print();
SubClass().SetA(123).SetB(123.4).Print();
SuperClass().SetA(123).Print();
}
I'm using VC2005, is there any alternative?
您可以自己编写 is_same
和 conditional
特征:
template <bool b, typename T, typename F>
struct conditional
{
typedef F type;
};
template <typename T, typename F>
struct conditional<true, T, F>
{
typedef T type;
};
template <typename T, typename U>
struct is_same
{
static const bool value = false;
};
template <typename T>
struct is_same<T, T>
{
static const bool value = true;
};
template <typename T = void>
class SuperClassCRTP
{
typedef typename conditional<is_same<T, void>::value
, SuperClassCRTP
, T>::type CRTP;
// ...
typedef SuperClassCRTP<> SuperClass;
int main()
{
SubClass().SetB(123.4).SetA(123).Print();
SubClass().SetA(123).SetB(123.4).Print();
SuperClass().SetA(123).Print();
}
关于c++ - 从父类(super class)函数返回子类定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25994397/