C++ C++;每个派生类中有不同的常量成员,如何移动函数以消除访问中的重复?

C++ C++;每个派生类中有不同的常量成员,如何移动函数以消除访问中的重复?,c++,inheritance,static,refactoring,code-duplication,C++,Inheritance,Static,Refactoring,Code Duplication,我有一些派生类,它们在某些常量属性上有所不同。在所有派生类中,我都有一个返回属性的函数。有没有办法将get_x函数移到基类中以消除重复?我在这条帖子和很多谷歌搜索中都找到了,但我找不到我想要的东西: 我希望它看起来像这样,但这不起作用,因为x没有在base中定义。我还尝试了extern、staticconst属性x等 class Derived1: public Base{ static const attribute x = SOME_ATTRIBUTE1; }; class De

我有一些派生类,它们在某些常量属性上有所不同。在所有派生类中,我都有一个返回属性的函数。有没有办法将get_x函数移到基类中以消除重复?我在这条帖子和很多谷歌搜索中都找到了,但我找不到我想要的东西:

我希望它看起来像这样,但这不起作用,因为x没有在base中定义。我还尝试了extern、staticconst属性x等

class Derived1: public Base{
    static const attribute x = SOME_ATTRIBUTE1;
};

class Derived2: public Base{
    static const attribute x = SOME_ATTRIBUTE2;
};

class Base{
    attribute get_x(){
        return x;
    }
};

谢谢。

好吧,根据类的其他部分的外观,它可能是模板而不是多态继承的好用例:

template <attribute X>
class Base{
    attribute get_x(){
        return X;
    }
}

typedef Base<SOME_ATTRIBUTE1> Derived1;
typedef Base<SOME_ATTRIBUTE2> Derived2;
模板
阶级基础{
属性get_x(){
返回X;
}
}
typedef-Base-Derived1;
typedef-Base-Derived2;

有点笨拙,但您可以使用类似于以下内容的方法来实现这一点:

template <attribute x> class Base
{
    public:
        attribute get_x ( ) { return x; }
};

class Derived1 : public Base<SOME_ATTRIBUTE_1>
{
    ...
};

class Derived2 : public Base<SOME_ATTRIBUTE_2>
{
    ...
};
编辑:请注意,模板方法可以扩展到所需的任意多个属性,如下所示:

template <attribute1 x, attribute2 y ...> class Base
{
    public:
        attribute get_x ( ) { return x; }
        attribute get_y ( ) { return y; }
        ...
};
class Base
{
    public:
        Base (attribute newX) : x(newX) { }
        attribute get_x ( ) { return x; };
    protected:
        const attribute x;
};

class Derived1 : public Base
{
    public:
        Derived1 ( ) : Base(SOME_ATTRIBUTE_1) { }
};

class Derived2 : public Base
{
    public:
        Derived2 ( ) : Base(SOME_ATTRIBUTE_2) { }
};
在这里,每个
派生的
都有一个该类独有的常量属性。如果愿意,您当然可以删除
常量。

\include
#include <iostream>
#include <typeinfo>

enum attribute {SOME_ATTRIBUTE1, SOME_ATTRIBUTE2};

class Base
{
public:
    virtual attribute get_x() = 0;
};

template <attribute Attr>
class Derived : public Base
{
public:
    virtual attribute get_x() {return Attr;}
};

typedef Derived<SOME_ATTRIBUTE1> Derived1;
typedef Derived<SOME_ATTRIBUTE2> Derived2;

int main()
{
    std::cout << typeid(Derived1().get_x()).name() << '\n';
    return 0;
}
#包括 枚举属性{SOME_ATTRIBUTE1,SOME_ATTRIBUTE2}; 阶级基础 { 公众: 虚拟属性get_x()=0; }; 模板 派生类:公共基 { 公众: 虚拟属性get_x(){return Attr;} }; 派生派生的类型定义1; 衍生衍生的typedef 2; int main() {
std::你能不能不使用常数指针之类的东西。它可以在派生类irc中实例化。虽然这个问题并不完全清楚,但Derived1和Derived2似乎应该是从同一个基类继承的。-我认为第二个代码段没有错。@visitor:是的,我没有这样做虽然
Base
Base
实际上是不同的类。这要归咎于通常尽可能避免模板编程。也就是说,IIRC通过虚拟继承可以实现一些更合适的功能,其中模板虚拟继承自一个单独的
Base
类。可能。嗨,谢谢解决方案。如果我只有一个属性,第一个会很好,第二个通常会很有用。我只是认为属性应该是成员(因为它们是类的一些属性),但可能没什么可以做的?谢谢!@AWU:模板方法可以扩展到更多属性,你的其他评论启发我选择另一个选项,每个类都有自己的
属性作为属性。请参阅我上面的编辑。谢谢!我不知道模板可以是这样的。这些都是很好的答案!我想想OP对术语“派生”的使用建议讨论中的类应该共享一个公共基类,其中的
get_x
方法将被移动到该基类。顺便说一句,调用模板类
base
并调用它的实例化
Derived
有点混乱。@ltjax:请参阅修改后的代码。这将使用VC9编译并输出
enum属性
。是否正确有什么我遗漏的吗?是的,我想我已经错过了。只有“整数”类型可以是模板参数,所以整数和枚举都可以工作。用户定义的结构不会。
class Base
{
    public:
        Base (attribute newX) : x(newX) { }
        attribute get_x ( ) { return x; };
    protected:
        const attribute x;
};

class Derived1 : public Base
{
    public:
        Derived1 ( ) : Base(SOME_ATTRIBUTE_1) { }
};

class Derived2 : public Base
{
    public:
        Derived2 ( ) : Base(SOME_ATTRIBUTE_2) { }
};
#include <iostream>
#include <typeinfo>

enum attribute {SOME_ATTRIBUTE1, SOME_ATTRIBUTE2};

class Base
{
public:
    virtual attribute get_x() = 0;
};

template <attribute Attr>
class Derived : public Base
{
public:
    virtual attribute get_x() {return Attr;}
};

typedef Derived<SOME_ATTRIBUTE1> Derived1;
typedef Derived<SOME_ATTRIBUTE2> Derived2;

int main()
{
    std::cout << typeid(Derived1().get_x()).name() << '\n';
    return 0;
}