3

我想弄清楚如何安排一些课程。这就是我到目前为止所得到的......

继承层次结构的顶部(自然)是 T:

(T.h)
namespace foo
{
    class T
    {
    public:
        virtual void method1(std::string a_parameter) = 0;
        virtual void method2() = 0;
    };
}

我有两个 T 子类和一些额外的方法 - 这里是头文件:

(A.h)
namespace foo
{
    class A : public T
    {
    public:
        virtual ~A() {};
        virtual void method3() = 0;
        //and a factory function
        static A* gimmeAnAyy();
    };
}

(B.h)
namespace foo
{
    class B : public T
    {
    public:
        virtual ~B() {};
        virtual void method4() = 0;
        //and a factory function
        static B* gimmeABee();
    };
}

实现类位于各自的 .cpp 文件中:

(A.cpp)
namespace foo
{
    class AImpl : public A
    {
    public:
        A(std::string member_data) : m_member_data(member_data) {};
        ~A() {};
        void method3()
        {
            //something really important, can't think of it right now ;-)
        };
    private:
        std::string m_member_data;
    };
    A* A::gimmeAnAyy()
    {
        return new AImpl("this is an impl of A");
    }; 
}

(B.cpp)
namespace foo
{
    class BImpl : public B
    {
    public:
        B(std::string other_data) : m_other_data(other_data) {};
        ~B() {};
        void method4()
        {
            //something really important, can't think of it right now ;-)
        };
    private:
        std::string m_other_data;
    };
    B* B::gimmeABee()
    {
        return new BImpl("this is an imll of B");
    }; 
}

现在编译器抱怨我没有在 AImpl 和 BImpl 中实现的虚函数 method1() 和 method2() 是正确的。

我想要的是一个 AImpl 和 BImpl 都可以继承的 TImpl 类,这样我就不必在两个不同的 .cpp 文件中实现 method1() 和 method2() 。

可能吗?我出去吃午饭了吗?我是否对 StackExchange 帖子提出了太多反问?

提前致谢,

麦克风

4

5 回答 5

1

是的,这是可能的。通常的做法是使用以下代码段:

template<typename Interface>
class TImpl : public Interface
{
public:
    virtual void method1(std::string a_parameter) { /* implementation */ }
    virtual void method2() { /* implementation */ }
};

然后从它继承如下:

class Aimpl : public TImpl<A>
{
public:
    virtual void method3() { /* implementation */ }
};

class Bimpl : public Timpl<B>
{
public:
    virtual void method4() { /* implementation */ }
};

您可以将 Timpl 的实现放在 cpp 文件中,但是您必须为每个可能的接口显式实例化它。这在 cpp 中按如下方式完成:

template<typename Interface>
void Timpl<Interface>::method1(std::string a_parameter)
{
    /* implementation */
}

template<typename Interface>
void Timpl<Interface>::method2()
{
    /* implementation */
}

template class Timpl<A>;
template class Timpl<B>;
于 2014-02-17T17:05:28.670 回答
0

不要让 method1 和 method2 成为纯虚函数。给他们一个实施!

IE

宣布

class T
    {
    public:
        virtual void method1(std::string a_parameter);
        virtual void method2();
    };

定义:

void T::method1(std::string a_parameter) { // Could use const/reference here perhaps

....

}

ETC...

于 2013-08-28T01:37:03.567 回答
0

在 A 和 B 类声明中,方法 3 和 4 是纯虚拟的,因此在定义文件中您不应该给出它们的实现。据我了解,A 和 B 将 T 方法和他们自己的虚拟方法的实现引导到从它们继承的其他具体类。如果您认为 A 和 B 是具体类,请从以下几行中删除“= 0”:

class A : public T
{
public:
    virtual ~A() {};
    virtual void method3() = 0; // <-- Here
    //and a factory function
    static A* gimmeAnAyy();
};

class B : public T
{
public:
    virtual ~B() {};
    virtual void method4() = 0; // <-- and Here
    //and a factory function
    static B* gimmeABee();
};

如果不想实现 T 类的方法 1 和 2,则在 T 类或 A 类和 B 类中给它们一个空的或默认的实现。

但是考虑到这一点,如果您从一个接口继承,那么您应该实现接口。:)

于 2013-08-28T02:20:13.290 回答
0

看来你的问题是错误的认为最好virtual在你的基类中只有纯函数!只需克服它并在T. 尽管有宗教信仰是不好的,但没有任何技术上的理由不拥有它。坚持在基类中只包含纯virtual函数就像坚持所有音乐都必须是12 音音乐

于 2013-08-28T01:39:04.100 回答
0

因为两个子类(A & B)都没有(method1,method2),所以你不必使用虚拟。您可以轻松地在基类中提供默认实现,然后通过继承链调用和使用这些方法,因为这里的继承类型是公共的。

于 2013-08-28T01:58:41.783 回答