模板运算符重载基类

时间:2013-02-20 18:03:32

标签: c++ oop templates operator-overloading base-class

我有一个包含许多子类的基类。如何在基类中的加载器上实现模板运算符以适用于所有继承类?我尝试使用+运算符制作一个,但它抱怨我有太多的参数。我真的不确定这是做正确的事情(我刚刚开始使用OOP),所以如果你能想到一个更好的方式,那也很棒。

我正在创建一个库,其中每个度量空间都是一个类。我想创建一个每个空间继承的基类“操作”。

我的模板基类:

#ifndef __libSpace__Operations__
#define __libSpace__Operations__

template< typename T >
class Operations{
public:
    friend T operator+( const T& sp, const T& nsp ){
        return T(sp.dimension + nsp.dimension);
    };
};

#endif

子:

#ifndef __libSpace__EuclidSP__
#define __libSpace__EuclidSP__

#include "Operations.h"

class EuclidSP: public Operations<EuclidSP>{
public:
    EuclidSP(int n = 0, ...);
    ~EuclidSP();

    double* vector();

private:
    int dimension;
    double *vec = new double(dimension);
};

#endif

主:

#include <iostream>
#include "EuclidSP.h"

int main(int argc, const char * argv[])
{
EuclidSP ob1(3,4.0,5.0,6.0);
EuclidSP ob2(3,2.0,5.0,3.0);
EuclidSP obj3();

obj3 = ob2+ob1;

return 0;
}

2 个答案:

答案 0 :(得分:1)

成员operator +()只有一个参数,即右操作数。左边或第一个始终是*this。根据您的具体情况,您只需要基础+,虚拟+或模板。一个免费operator +()采取两个论点,“左”和“右”。

在您的代码中:

template< typename T >
class Operations{
public:
    friend T operator+( const T& sp, const T& nsp ){
        return T(sp.dimension + nsp.dimension);
    };
};

你是会员还是朋友?

如果是朋友,问题是+()必须在课外定义,它只是朋友,而不是会员。

template< typename T >
    T operator+( const T& sp, const T& nsp );

template< typename T >
class Operations{
public:
    friend T operator+<T>( const T& sp, const T& nsp );

};

template< typename T >
    T operator+( const T& sp, const T& nsp )
    {
        return T(sp.dimension + nsp.dimension);
    }

但是!!!!现在你有了REAL问题:+()使用派生类的privat成员,而不是基类,所以它需要是派生类的朋友。我想你需要重新思考;-)你的设计。如果你在Operations中使用维度这么舒服..它可能是一个受保护的操作成员吗???您的所有操作都有维度?

答案 1 :(得分:0)

您的基类应该通过接收它作为模板参数来了解派生类型类,并将operator+实现为friend

template< typename T >
class base
{
    friend T operator+( const T& lhs, const T& rhs )
    {
       // your generic implementation here...
    }
};
然后派生类派生自基类,如下所示:

class D1 : public base<D1> { ... };
class D2 : public base<D2> { ... };