c++ - 从父类(super class)函数返回子类定义

标签 c++ templates inheritance

我有两个 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?

DEMO

#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_sameconditional 特征:

DEMO

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/

相关文章:

c++ - 容器元素可以使用 `std::pmr::map` 的分配器进行分配吗?

c++ - 在 new 表达式中分配内存后是否评估初始值设定项?

c++ - 用于模板继承的嵌套类前向声明

c++ - Constexpr 作为模板函数中的数组大小(GCC 与 Intel)

c++ - extern 模板不适用于 gcc?

javascript - 一个关于javascript中Array继承的问题

c++ - 将整数常量映射到类型

具有静态成员的 C++ 寄存器模式有效 "sometimes"

java - 从抽象类派生时如何遵守equals()的契约

具有模板类和动态调度的 C++ 共享指针