Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何让模板typename类的两个(或多个)实例使用相同的函数_C++_Templates_Instances_Typename - Fatal编程技术网

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

C++ 如何让模板typename类的两个(或多个)实例使用相同的函数,c++,templates,instances,typename,C++,Templates,Instances,Typename,我想知道是否有可能有一个类使用模板,其函数是“typename T”默认使用的。我将举几个例子: 标题: includes all here extern template class Object<rectangleBase> extern template class Object(circleBase> struct rectangleBase { int width, height; int posX, posY; }; struct circleB

我想知道是否有可能有一个类使用
模板
,其函数是“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;
};
包括这里的所有内容
外部模板类对象
外部模板类对象(circleBase>
结构矩形基
{
int宽度、高度;
int-posX,posY;
};
结构循环库
{
整数半径;
int-posX,posY;
};
模板
类对象{
公众:
对象();
~Object();
无效移动位置(整数x,整数y);
无效设置位置(整数x,整数y);
T&returnObject(){
返回对象;
}
私人:
T对象;
};
资料来源:

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;
}
包括这里的所有内容
模板类对象
模板类对象
对象::对象(){
矩形基*新对象;
newObject=新矩形基;
object=*newObject;
}
对象::对象(){
圆圈基*新对象;
newObject=新的循环库;
object=*newObject;
}
void对象::movePos(intx,inty){//here
object.posX+=x;
object.posY+=y;
}
void对象::setPos(intx,inty){//here
object.posX=x;
object.posY=y;
}
使用函数setPos和movePos,
是否都可以使用相同的函数,而不必写两次相同的代码,因为它们使用的代码完全相同,我已经显示了函数在代码中的位置

如果不可能,是否有替代方案?

是,您可以:

template <typename T>
void Object<T>::movePos(int x, int y) {
    object.posX += x;
    object.posY += y;
}
模板
void对象::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;
}
模板
对象::对象(){
//实际上,这与默认值没有什么不同
//对象的构造函数,但泄漏了T的一个实例。
T*newObject;
newObject=newt;
object=*newObject;
}
模板通常需要头文件中的整个实现,但如果您对接受的有限类型没有问题,则可以明确实例化类,然后在源文件中实现:

在头文件中(定义类后的任意位置):

extern模板类对象;
外部模板类对象;
在源文件中(定义方法后的任意位置):

模板类对象;
模板类对象;

除了
rectangleBase
circleBase
之外的任何其他类型都不能用于此设置。

我不确定您的问题出在哪里。您应该简单地实现您的功能,实例化模板并使用您的对象

我试过了,这个,它有效。请看一下:

#包括
结构矩形基
{
int宽度、高度;
int-posX,posY;
};
结构循环库
{
整数半径;
int-posX,posY;
};
模板
类对象{
公众:
对象(){}
~Object(){}
无效移动位置(整数x,整数y)
{
object.posX+=x;
object.posY+=y;
}
无效设置位置(整数x,整数y)
{
object.posX=x;
object.posY=y;
}
T&returnObject(){return object;}
私人:
T对象;
};
int main(int argc,字符**argv)
{
对象a;
对象b;
b、 setPos(1,2);
printf(“px:%d”,b.returnObject().posX);
}
如果您对函数编译器将生成多少实例感兴趣, (例如:函数的代码非常庞大),编译器很可能会生成与不同实例相同数量的相似代码实例。优化器可能会折叠其中一些实例。但优化器是否会这样做?这很难说


直接使用模板主体中的参数类型的字段、方法、枚举等时的方法使用依赖类型调用。是的,这种方法使得使用不具有此字段或成员函数的类型实例化模板变得困难或不可能。然而,这种模式被广泛使用。

多个不同数据类型的相同代码(简而言之,是泛型编程)正是模板的用途。我认为您考虑得太多了。以下内容对于您的用例来说已经足够了:

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;
};

为什么你要用完全相同的行为明确地专门化你的类?对不起,我没有理解你@QuentinI不理解这个问题:你只实现了一次
movePos
setPos
。关于你的代码,真正让人担心的是你在泄漏内存:当你调用
newcirclebase
ne时w rectangleBase
您永远不会释放内存。此外,您实际上不需要显式调用
new
,因为如果
t
具有默认构造函数(或者如果您编写了
Object()
的专用版本),
对象将始终使用空对象进行初始化(现在您也在制作一个副本,并将其分配给
对象
)。您正在专门化构造函数,即使它的代码与模板参数完全相同。为什么?如果您只使用基本模板,它的所有函数实际上只会“共享”相同的代码。这应该是
对象::setPos()
?在放置
外部模板类对象时;
有一个错误,表示
外部模板无法跟随类“对象”的显式实例化
对象也一样@StenSoft@Jack
外部模板类
必须在
模板类
之前。源文件中的
#include
s似乎有点错误。
模板类
必须在头文件的
#include
之后,否则它将不知道实例化什么(
#include
s通常应该在任何其他内容之前)。上面的代码已更改为我如何使用它,是否正确?如果是,则
仍会给我相同的错误@StenSoft@Jack
外部模板类
需要在类i之后
template class Object<rectangleBase>;
template class Object<circleBase>;
#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);
}
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;
};
Object<rectangleBase> r;
r.setPos(5, 6);

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