Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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

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++ 从具有运算符重载的类派生_C++_Templates - Fatal编程技术网

C++ 从具有运算符重载的类派生

C++ 从具有运算符重载的类派生,c++,templates,C++,Templates,我想创建一个类集合,这些类的行为类似于数学向量,因此将一个对象乘以一个标量将每个字段乘以该数量,等等。问题是我希望字段具有实际名称,而不是作为索引处理 我实现这一点的最初想法是使用重载创建基类Rn,然后使用漂亮的名称创建派生类。大概是这样的: #include <iostream> #include <algorithm> using namespace std; template<int N, class X=double> struct Base{

我想创建一个类集合,这些类的行为类似于数学向量,因此将一个对象乘以一个标量将每个字段乘以该数量,等等。问题是我希望字段具有实际名称,而不是作为索引处理

我实现这一点的最初想法是使用重载创建基类Rn,然后使用漂亮的名称创建派生类。大概是这样的:

#include <iostream>
#include <algorithm>
using namespace std;

template<int N, class X=double>
struct Base{
    X xs[N];

    Base(){};

    Base(X *data){
        copy(data, data+N, xs);
    }

    Base operator*= (double d){
        for(int i=0; i<N; i++){
            xs[i] *= d;
        }
        return *this;
    }

    Base operator* (double d){
        Base answer = *this;
        answer *= d;
        return answer;
    }

    //also operators for +=, +, multiplication from left, maybe [] too
};

struct Derived : public Base<2>{
    Derived(double a, double b){
        foo() = a;
        bar() = b;
    }

    double &foo(){ return xs[0]; }
    double &bar(){ return xs[1]; }
};

int main()
{
    //this is OK:
    double data[2] = {0.0, 2.0};
    Base<2> b(data);
    b = b*17.0;

    cout << b.xs[0] << endl;

    //I can't do this:
    Derived x(0.0, 2.0);
    x = x*17.0;

    cout << x.foo() << endl;

    return 0;
}
#包括
#包括
使用名称空间std;
模板
结构基{
xxs[N];
Base(){};
基数(X*数据){
复制(数据,数据+N,xs);
}
基本运算符*=(双d){

对于(inti=0;i我认为使用枚举或静态常量来命名字段会更好

e、 例如,静态常量int字段_NAME=0;
静态常量int字段_NAME2=1

然后您可以使用std::valarray或boost::ublas::vector/matrix类型来利用现有代码并获得高质量的性能向量操作来引导。

您的基本运算符(*在本例中为)可以接受派生对象,但它们返回一个基,该基不能用作派生默认赋值运算符中的右操作数。解决此问题的最简单方法是向派生添加一个赋值运算符,该运算符将采用一个基:

Derived& operator= (const Base<2>& other)
派生运算符=(常量基和其他)

您必须将其添加到任何派生类中,但实现相当简单(您可以在Base中使用void CopyOtherBase函数来执行复制,并让all operator=调用它并返回*this)。

我将只讨论技术难点,而不讨论这是否是一个好主意

问题是,运算符*of Derived的结果是一个基,而运算符=of Derived(这是一个默认运算符=)不知道如何“吃”一个基

一个简单的解决方案是创建一个派生的构造函数,该构造函数获取一个基,并执行正确初始化自身所需的任何操作。这将允许将一个基动态转换为派生的,并适用于除基之外的所有其他派生运算符

类似于-

Derived(const Base<2>& B) : Base<2>( B )
{
}
派生(常量基&B):基(B)
{
}

模板元编程有一个有趣的想法,就是用数学向量来解决这类问题,但可能无法解决零件命名的问题

David Abrahams,Aleksey Gurtovoy:C++模板元编程:从Boost和Excel中的概念、工具和技术,Addison Wesley,ISBN 031-1-227 25-5/P>< P>,

所有重载运算符,除了 赋值(运算符=)是继承的 通过派生类


这可能是您的问题吗?

memcpy通常是个坏主意。如果base不是POD,代码可能会严重中断。更喜欢使用更惯用的:派生的(const base&b):base(b){}这应该返回派生的(*尤其是this)。它不允许operatorX=,因为我相信您需要提供完整的外观。当然,您是对的。谢谢您的更正,我修正了我的答案。
Derived(const Base<2>& B) : Base<2>( B )
{
}