C++ 在继承中更改成员类型

C++ 在继承中更改成员类型,c++,templates,inheritance,C++,Templates,Inheritance,给定一个基类base,它有两个派生类,DerA和DerB,派生类是否可以有一个成员变量用于base成员函数,但每个类的类型不同 class Base { * a // Declare a as *something*, so it can be used by "doWork" template <typedef T> void doWork(T b) { // Add another value to "a" which is of its same ty

给定一个基类
base
,它有两个派生类,
DerA
DerB
,派生类是否可以有一个成员变量用于
base
成员函数,但每个类的类型不同

class Base {
    * a // Declare a as *something*, so it can be used by "doWork"

    template <typedef T>
    void doWork(T b) { // Add another value to "a" which is of its same type
        a += b; // For example; an operation that works on "a", no matter what numeric type it is
    }
}

class DerA : public Base {
    // Make "a" an int
}

class DerB : public Base {
    // Make "a" a float
}
类基{
*a//将a声明为*something*,以便“doWork”可以使用它
模板
void doWork(tb){//为“a”添加另一个相同类型的值
a+=b;//例如,对“a”起作用的操作,不管它是什么数字类型
}
}
DerA类:公共基地{
//把“a”变成int
}
类DerB:公共基{
//使“a”成为浮点数
}
实际上,
a
将是基本结构,而
DerA
DerB
将具有基本结构的派生版本(每个派生类都有特定于其用途的结构的派生形式,但每个派生类都必须在
a
上执行简单操作,因此,当我可以只使用模板函数时,为每个派生类复制/粘贴该简单函数似乎毫无意义)。我只想键入
a
作为基本结构类型,但随后我将无法访问每个派生结构所具有的各种专门成员函数和变量(如果我正确理解继承)


如果这个问题是重复的,我很抱歉,但我不知道这种质量会被称为什么,所以谷歌搜索被证明是徒劳的。

你可能想要的是

请注意,
doWork
的每个版本都必须有效,才能调用每个
Der
s,因为
Base\u helper
实例化了它们


如果传递给
doWork
的类型是无界的,而
Der
的类型是有界的,那么您只能向后执行上面的操作。但是,这会变得很尴尬。在这种情况下,您最好使用
boost::variant
类型解决方案。

我想您想要实现这样的目标:

template<typedef T>
class Base {
    T a;
    void doWork(T b) { // Add another value to "a" which is of its same type
        a += b; // For example; an operation that works on "a", no matter what numeric type it is
    }
}

class DerA : public Base<int> {
}

class DerB : public Base<float> {
}
模板
阶级基础{
Tα;
void doWork(tb){//为“a”添加另一个相同类型的值
a+=b;//例如,对“a”起作用的操作,不管它是什么数字类型
}
}
DerA类:公共基地{
}
类DerB:公共基{
}
或者您可以完全转储类DerA和DerB,并改用typedefs:

typedef Base<int> DerA;
typedef Base<float> DerB;
typedef基本DerA;
typedef-Base-DerB;

这可以用类似的模式轻松解决:

template<class D> // Base class is templated
class Base {
public:
    D a;
    void doWork(D b) {
        a += b;
    }
};

class DerA : public Base<int> {};

class DerB : public Base<float> {};
template//基类已模板化
阶级基础{
公众:
D a;
空榫(D b){
a+=b;
}
};
DerA类:公共基{};
类DerB:公共基{};


编辑:如果您只需要一个公共基(
base
是与
base
完全不同的类型),您可以使用接口类并从中继承base。

既然如此,我不明白为什么is不应该是
模板类Der{T T;模板void doWork(kb){a+=b;};typedef Der DerA;typedef Der DerB;}
用一种更好的方式来表达我之前的评论,在这种情况下你为什么要为多态性而烦恼呢?这似乎是一个模板类的简单应用程序。你需要将
DerA*
s和
DerB*
s作为
Base*
s传递吗?我希望不是这样。@MadScienceDreams,实际上,claSSE比显示的要复杂得多。请原谅我没有解释。你是对的,模板化整个类会很有用,但如果可以避免的话,我不想模板化每个类,特别是因为这只是类的一个小函数。@sgbrown没问题。简单提示一下:CRTP仍然使用模板化基类,所以如果你尝试提供一个接口时,您只需要一个
iBase
非模板接口类,并从中继承
Base
。但是
DerA
DerB
都有两个不同的基类。OP要求“基类的派生版本”。我正在添加另一个类似CRTP的详细信息。这可能是处理我的问题的最佳方法,谢谢!不幸的是,我确实需要它们从一个公共基继承,并且仅仅为这一个小问题添加一个继承类(更容易为每个派生重写一个虚拟方法:P)并不值得删除我所有的现有代码。但是,如果其他人有类似的问题,我认为这是最好的解决方案,是对CRTP的有趣尝试。再次感谢!哇,这是一些非常有趣的代码!有点…CRTP在类固醇上。非常感谢分享,我想我可能会使用此解决方案。@sgbrown为了获得更多的功能,
self()->doWork\u impl(x)
内部
doWork
而不是
doWork\u impl(x)
DerX
类选择性地覆盖
doWork\u impl
,并将其静态调度到。如果它们不这样做,则调用
Base\u helper::doWork\u impl
。基本上我们是在类型擦除自己。
typedef Base<int> DerA;
typedef Base<float> DerB;
template<class D> // Base class is templated
class Base {
public:
    D a;
    void doWork(D b) {
        a += b;
    }
};

class DerA : public Base<int> {};

class DerB : public Base<float> {};