如何使用模板typename类的两个(或更多)实例使用相同的函数

时间:2015-07-12 20:11:57

标签: c++ templates instances typename

我想知道是否有可能让一个使用template<typename T>的类具有'typename T'默认使用的函数。我举个例子:

部首:

includes all here
extern template class Object<rectangleBase>
extern template class Object(circleBase>

struct rectangleBase
{
    int width, height;
    int posX, posY;
};

struct circleBase
{
    int radius;
    int posX, posY;
};

template<typename T>
class Object {
public:
    Object();
    ~Object();

    void movePos(int x, int y);

    void setPos(int x, int y);

    T& returnObject() {
        return object;
    }
private:
    T object;
};

来源:

includes all here
template class Object<rectangleBase>
template class Object<circleBase>

Object<rectangleBase>::Object() { 
    rectangleBase* newObject;
    newObject = new rectangleBase;
    object = *newObject;
}

Object<circleBase>::Object() {
    circleBase* newObject;
    newObject = new circleBase;
    object = *newObject;
}

void Object::movePos(int x, int y) { //here
    object.posX += x;
    object.posY += y;
}

void Object::setPos(int x, int y) { //here
    object.posX = x;
    object.posY = y;
}

使用函数setPos和movePos,<rectangleBase><circleBase>是否可以使用相同的函数而不是我必须将相同的代码写两次,因为它们将使用完全相同的代码,我已经在代码中显示了函数的位置。

如果不可能,还有替代方案吗?

3 个答案:

答案 0 :(得分:2)

为多种不同的数据类型(通用编程简而言之)提供相同的代码正是模板的用途。我觉得你过分思考了。以下内容足以满足您的使用情况:

template<typename T>
class Object {
public:
    Object()
    : object()
    { }

    void movePos(int x, int y) {
        object.posX += x;
        object.posY += y;
    }

    void setPos(int x, int y) {
        object.posX = x;
        object.posY = y;
    }

    T& returnObject() {
        return object;
    }
private:
    T object;
};

这就是你所需要的一切。这适用于任何默认可构造的T,如果movePos具有这两个成员变量,则可以调用setPosT。您根本不需要声明专业化。鉴于上述情况,以下工作正常:

Object<rectangleBase> r;
r.setPos(5, 6);

Object<circleBase> c;
c.setPos(10, 20);
s.movePos(10, 10);

答案 1 :(得分:0)

是的,你可以:

template <typename T>
void Object<T>::movePos(int x, int y) {
    object.posX += x;
    object.posY += y;
}

即使你的构造函数也可以使用这种方法:

template <typename T>
Object<T>::Object() {
    // This in fact does nothing really different than the default
    // constructor of object but leaks one instance of T.
    T* newObject;
    newObject = new T;
    object = *newObject;
}

模板通常需要头文件中的整个实现,但如果你接受的类型有限,你可以明确地实例化类,然后你可以在源文件中实现:

在头文件中(定义类之后的任何地方):

extern template class Object<rectangleBase>;
extern template class Object<circleBase>;

在源文件中(定义方法后的任何位置):

template class Object<rectangleBase>;
template class Object<circleBase>;

rectangleBasecircleBase以外的任何其他类型都无法使用此设置。

答案 2 :(得分:0)

我不确定你的问题是什么。您应该只是实现您的函数,实例化模板并使用您的对象。

我试过,这个,它有效。请看一下:http://ideone.com/717044

#include <stdio.h>

struct rectangleBase
{
    int width, height;
    int posX, posY;
};

struct circleBase
{
    int radius;
    int posX, posY;
};

template<typename T>
class Object {
public:

    Object() { }
    ~Object() { }

    void movePos(int x, int y)
    {
        object.posX += x;
        object.posY += y;
    }

    void setPos(int x, int y)
    {
        object.posX = x;
        object.posY = y;
    }

    T& returnObject() { return object; }

private:
    T object;
};

int main(int argc, char ** argv)
{
    Object<rectangleBase> a;
    Object<circleBase> b;
    b.setPos(1,2);
    printf("px: %d", b.returnObject().posX);
}

如果您对函数编译器将生成多少个实例感兴趣, (例如:函数的代码很大),编译器很可能会生成与您拥有的许多不同实例一样多的类似代码实例。优化器可能会崩溃其中一些。但是如果优化器会这样做或不这样做 - 这很难说。

当您使用依赖类型直接调用模板正文中的参数类型的字段,方法,枚举等时的方法。是的,这种方法很难或不可能使用没有此字段或成员函数的类型来实例化模板。然而,这种模式被广泛使用。